* Re: [patch 1/9] [PATCH] qeth: convert to hw_features part 2
From: Michał Mirosław @ 2011-05-10 14:33 UTC (permalink / raw)
To: Frank Blaschka; +Cc: davem, netdev, linux-s390
In-Reply-To: <20110510140936.GA39624@tuxmaker.boeblingen.de.ibm.com>
W dniu 10 maja 2011 16:09 użytkownik Frank Blaschka
<blaschka@linux.vnet.ibm.com> napisał:
> On Tue, May 10, 2011 at 03:19:27PM +0200, Michał Mirosław wrote:
>> From: Frank Blaschka <frank.blaschka@de.ibm.com>
>> > Set rx csum default to hw checksumming again.
>> > Remove sysfs interface for rx csum (checksumming) and TSO (large_send).
>> > With the new hw_features it does not work to keep the old sysfs
>> > interface in parallel. Convert options.checksum_type to new hw_features.
>> [...]
>> > @@ -1482,32 +1476,28 @@ static int qeth_l3_start_ipa_checksum(st
>> [...]
>> > - rc = qeth_l3_send_checksum_command(card);
>> > - if (!rc)
>> > - dev_info(&card->gdev->dev,
>> > + card->dev->hw_features &= ~IPA_INBOUND_CHECKSUM;
>> > + card->dev->features &= ~IPA_INBOUND_CHECKSUM;
>> > + return 0;
>> > + }
[...]
>> Don't modify hw_features. Limit currently available features in
>> ndo_fix_features callback instead when checksumming is (temporarily)
>> unavailable.
>>
> We have a recovery operation in our driver. What can we do in case this
> recovery detects the checksumming is not available anymore (during runtime
> of the device). ndo_fix_features callback does not come into play at this time.
> How can we solve this?
Just call netdev_update_features() after recovery.
>> > static int qeth_l3_set_features(struct net_device *dev, u32 features)
>> > {
>> > - enum qeth_checksum_types csum_type;
>> > struct qeth_card *card = dev->ml_priv;
>> > u32 changed = dev->features ^ features;
>> > + int on;
>> >
>> > if (!(changed & NETIF_F_RXCSUM))
>> > return 0;
>> >
>> > if (features & NETIF_F_RXCSUM)
>> > - csum_type = HW_CHECKSUMMING;
>> > + on = 1;
>> > else
>> > - csum_type = SW_CHECKSUMMING;
>> > + on = 0;
>> >
>> > dev->features = features ^ NETIF_F_RXCSUM;
>> > - return qeth_l3_set_rx_csum(card, csum_type);
>> > + return qeth_l3_set_rx_csum(card, on);
>> > }
>>
>> Since you removed dev->features update from qeth_l3_set_rx_csum(), you
>> should also modify this code to match. On exit from ndo_fix_features,
>> dev->features should reflect what is currently set, even if part of
>> the request failed.
> Do you mean qeth_l3_set_rx_csum should set dev->features dependent of
> the result of the checksum hardware operation?
Yes. If it doesn't, then network core might pass packets needing
hardware checksumming for a device with TX checksumming disabled.
Best Regards,
Michał Mirosław
^ permalink raw reply
* [PATCH] ixgbe: RX ntuple feature must check num_rx_queues
From: Sebastian.Poehn @ 2011-05-10 14:21 UTC (permalink / raw)
To: netdev
The driver must check how much RX queues there are, not TX queues.
--- ixgbe_ethtool.c.orig 2011-05-10 16:18:00.313745560 +0200
+++ ixgbe_ethtool.c 2011-05-10 16:18:23.285747635 +0200
@@ -2349,9 +2349,9 @@ static int ixgbe_set_rx_ntuple(struct ne
/*
* Don't allow programming if the action is a queue greater than
- * the number of online Tx queues.
+ * the number of online Rx queues.
*/
- if ((fs->action >= adapter->num_tx_queues) ||
+ if ((fs->action >= adapter->num_rx_queues) ||
(fs->action < ETHTOOL_RXNTUPLE_ACTION_DROP))
return -EINVAL;
Signed-off-by: Sebastian Poehn <sebastian.poehn@belden.com>
DISCLAIMER:
Privileged and/or Confidential information may be contained in this
message. If you are not the addressee of this message, you may not
copy, use or deliver this message to anyone. In such event, you
should destroy the message and kindly notify the sender by reply
e-mail. It is understood that opinions or conclusions that do not
relate to the official business of the company are neither given
nor endorsed by the company.
Thank You.
^ permalink raw reply
* Re: Fw: oops during unregister_netdevice interface enslaved to bond - regression
From: Frank Blaschka @ 2011-05-10 14:20 UTC (permalink / raw)
To: Eric Dumazet; +Cc: davem, netdev, linux-s390, ELELUECK
In-Reply-To: <1305034619.2614.37.camel@edumazet-laptop>
On Tue, May 10, 2011 at 03:36:59PM +0200, Eric Dumazet wrote:
> Le mardi 10 mai 2011 à 15:14 +0200, Frank Blaschka a écrit :
>
> > I just checked todays net-next tree, problem is still there.
> > I don't have an x86 box, but I was able to reproduce the problem
> > with the dummy device (on s/390)
> >
> > # modprobe bonding
> > # modprobe dummy
> > # ifconfig bond0 up
> > # ifenslave bond0 dummy0
> > # rmmod dummy
>
> Here is the patch to fix this problem
>
Hi Eric,
your patch did the trick. With the patch applied I could not
reproduce the problem anyhow I use real or dummy device.
Thx for your help!
> Thanks again for your help.
>
> [PATCH net-2.6] net: dev_close() should check IFF_UP
>
> Commit 443457242beb (factorize sync-rcu call in
> unregister_netdevice_many) mistakenly removed one test from dev_close()
>
> Following actions trigger a BUG :
>
> modprobe bonding
> modprobe dummy
> ifconfig bond0 up
> ifenslave bond0 dummy0
> rmmod dummy
>
> dev_close() must not close a non IFF_UP device.
>
> With help from Frank Blaschka and Einar EL Lueck
>
> Reported-by: Frank Blaschka <blaschka@linux.vnet.ibm.com>
> Reported-by: Einar EL Lueck <ELELUECK@de.ibm.com>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> CC: Octavian Purdila <opurdila@ixiacom.com>
> ---
> net/core/dev.c | 10 ++++++----
> 1 file changed, 6 insertions(+), 4 deletions(-)
>
> diff --git a/net/core/dev.c b/net/core/dev.c
> index 856b6ee..9200944 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -1284,11 +1284,13 @@ static int dev_close_many(struct list_head *head)
> */
> int dev_close(struct net_device *dev)
> {
> - LIST_HEAD(single);
> + if (dev->flags & IFF_UP) {
> + LIST_HEAD(single);
>
> - list_add(&dev->unreg_list, &single);
> - dev_close_many(&single);
> - list_del(&single);
> + list_add(&dev->unreg_list, &single);
> + dev_close_many(&single);
> + list_del(&single);
> + }
> return 0;
> }
> EXPORT_SYMBOL(dev_close);
>
>
^ permalink raw reply
* Re: [patch 1/9] [PATCH] qeth: convert to hw_features part 2
From: Frank Blaschka @ 2011-05-10 14:09 UTC (permalink / raw)
To: Michał Mirosław; +Cc: davem, netdev, linux-s390
In-Reply-To: <BANLkTimUUXp5XiCtVoD+pJyQYcE_r25zyA@mail.gmail.com>
On Tue, May 10, 2011 at 03:19:27PM +0200, Michał Mirosław wrote:
> > From: Frank Blaschka <frank.blaschka@de.ibm.com>
> >
> > Set rx csum default to hw checksumming again.
> > Remove sysfs interface for rx csum (checksumming) and TSO (large_send).
> > With the new hw_features it does not work to keep the old sysfs
> > interface in parallel. Convert options.checksum_type to new hw_features.
> [...]
> > @@ -1482,32 +1476,28 @@ static int qeth_l3_start_ipa_checksum(st
> [...]
> > - rc = qeth_l3_send_checksum_command(card);
> > - if (!rc)
> > - dev_info(&card->gdev->dev,
> > + card->dev->hw_features &= ~IPA_INBOUND_CHECKSUM;
> > + card->dev->features &= ~IPA_INBOUND_CHECKSUM;
> > + return 0;
> > + }
>
> Should be NETIF_F_RXCSUM probably.
>
Thx for reviewing the patch, yes should be NETIF_F_RXCSUM
> Don't modify hw_features. Limit currently available features in
> ndo_fix_features callback instead when checksumming is (temporarily)
> unavailable.
>
We have a recovery operation in our driver. What can we do in case this
recovery detects the checksumming is not available anymore (during runtime
of the device). ndo_fix_features callback does not come into play at this time.
How can we solve this?
> [...]
> > static int qeth_l3_set_features(struct net_device *dev, u32 features)
> > {
> > - enum qeth_checksum_types csum_type;
> > struct qeth_card *card = dev->ml_priv;
> > u32 changed = dev->features ^ features;
> > + int on;
> >
> > if (!(changed & NETIF_F_RXCSUM))
> > return 0;
> >
> > if (features & NETIF_F_RXCSUM)
> > - csum_type = HW_CHECKSUMMING;
> > + on = 1;
> > else
> > - csum_type = SW_CHECKSUMMING;
> > + on = 0;
> >
> > dev->features = features ^ NETIF_F_RXCSUM;
> > - return qeth_l3_set_rx_csum(card, csum_type);
> > + return qeth_l3_set_rx_csum(card, on);
> > }
>
> Since you removed dev->features update from qeth_l3_set_rx_csum(), you
> should also modify this code to match. On exit from ndo_fix_features,
> dev->features should reflect what is currently set, even if part of
Do you mean qeth_l3_set_rx_csum should set dev->features dependent of
the result of the checksum hardware operation?
> the request failed.
>
> > static const struct ethtool_ops qeth_l3_ethtool_ops = {
> > @@ -3342,6 +3326,12 @@ static int qeth_l3_setup_netdev(struct q
> > if (!(card->info.unique_id & UNIQUE_ID_NOT_BY_CARD))
> > card->dev->dev_id = card->info.unique_id &
> > 0xffff;
> > + if (!card->info.guestlan) {
> > + card->dev->hw_features = NETIF_F_SG |
> > + NETIF_F_RXCSUM | NETIF_F_IP_CSUM |
> > + NETIF_F_TSO;
> > + card->dev->features = NETIF_F_RXCSUM;
> > + }
>
> All features except RXCSUM will be disabled by default. Is that the intent here?
Yes, it is.
>
> Best Regards,
> Michał Mirosław
^ permalink raw reply
* Re: [PATCH 1/2] net/stmmac: don't go through ethtool to start autonegociation
From: Giuseppe CAVALLARO @ 2011-05-10 13:47 UTC (permalink / raw)
To: David Decotigny
Cc: David S. Miller, Joe Perches, Stanislaw Gruszka, netdev,
linux-kernel
In-Reply-To: <1304986748-15809-2-git-send-email-decot@google.com>
On 5/10/2011 2:19 AM, David Decotigny wrote:
> The driver used to call phy's ethtool configuration routine to start
> autonegociation. This change has it call directly phy's routine to
> start autonegociation.
>
> IMPORTANT: initial version was hiding phy_start_aneg() return value,
> this patch returns it (<0 upon error).
>
> Tested: module compiles, NOT tested on real hardware.
> Signed-off-by: David Decotigny <decot@google.com>
Sorry for the delay, I'm doing some tests with the stmmac on a "real"
HW. I'll come back asap.
Regards
Peppe
> ---
> drivers/net/stmmac/stmmac_ethtool.c | 13 ++-----------
> 1 files changed, 2 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/net/stmmac/stmmac_ethtool.c b/drivers/net/stmmac/stmmac_ethtool.c
> index 6f5aaeb..9c05cf0 100644
> --- a/drivers/net/stmmac/stmmac_ethtool.c
> +++ b/drivers/net/stmmac/stmmac_ethtool.c
> @@ -236,17 +236,8 @@ stmmac_set_pauseparam(struct net_device *netdev,
> priv->flow_ctrl = new_pause;
>
> if (phy->autoneg) {
> - if (netif_running(netdev)) {
> - struct ethtool_cmd cmd = { .cmd = ETHTOOL_SSET };
> - /* auto-negotiation automatically restarted */
> - cmd.supported = phy->supported;
> - cmd.advertising = phy->advertising;
> - cmd.autoneg = phy->autoneg;
> - ethtool_cmd_speed_set(&cmd, phy->speed);
> - cmd.duplex = phy->duplex;
> - cmd.phy_address = phy->addr;
> - ret = phy_ethtool_sset(phy, &cmd);
> - }
> + if (netif_running(netdev))
> + ret = phy_start_aneg(phy);
> } else
> priv->hw->mac->flow_ctrl(priv->ioaddr, phy->duplex,
> priv->flow_ctrl, priv->pause);
^ permalink raw reply
* Re: Fw: oops during unregister_netdevice interface enslaved to bond - regression
From: Eric Dumazet @ 2011-05-10 13:36 UTC (permalink / raw)
To: Frank Blaschka, David Miller; +Cc: netdev, ELELUECK, Octavian Purdila
In-Reply-To: <20110510131438.GA41522@tuxmaker.boeblingen.de.ibm.com>
Le mardi 10 mai 2011 à 15:14 +0200, Frank Blaschka a écrit :
> I just checked todays net-next tree, problem is still there.
> I don't have an x86 box, but I was able to reproduce the problem
> with the dummy device (on s/390)
>
> # modprobe bonding
> # modprobe dummy
> # ifconfig bond0 up
> # ifenslave bond0 dummy0
> # rmmod dummy
Here is the patch to fix this problem
Thanks again for your help.
[PATCH net-2.6] net: dev_close() should check IFF_UP
Commit 443457242beb (factorize sync-rcu call in
unregister_netdevice_many) mistakenly removed one test from dev_close()
Following actions trigger a BUG :
modprobe bonding
modprobe dummy
ifconfig bond0 up
ifenslave bond0 dummy0
rmmod dummy
dev_close() must not close a non IFF_UP device.
With help from Frank Blaschka and Einar EL Lueck
Reported-by: Frank Blaschka <blaschka@linux.vnet.ibm.com>
Reported-by: Einar EL Lueck <ELELUECK@de.ibm.com>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
CC: Octavian Purdila <opurdila@ixiacom.com>
---
net/core/dev.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/net/core/dev.c b/net/core/dev.c
index 856b6ee..9200944 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1284,11 +1284,13 @@ static int dev_close_many(struct list_head *head)
*/
int dev_close(struct net_device *dev)
{
- LIST_HEAD(single);
+ if (dev->flags & IFF_UP) {
+ LIST_HEAD(single);
- list_add(&dev->unreg_list, &single);
- dev_close_many(&single);
- list_del(&single);
+ list_add(&dev->unreg_list, &single);
+ dev_close_many(&single);
+ list_del(&single);
+ }
return 0;
}
EXPORT_SYMBOL(dev_close);
^ permalink raw reply related
* Re: [patch 1/9] [PATCH] qeth: convert to hw_features part 2
From: Michał Mirosław @ 2011-05-10 13:19 UTC (permalink / raw)
To: frank.blaschka; +Cc: davem, netdev, linux-s390
In-Reply-To: <20110510115047.113084723@de.ibm.com>
> From: Frank Blaschka <frank.blaschka@de.ibm.com>
>
> Set rx csum default to hw checksumming again.
> Remove sysfs interface for rx csum (checksumming) and TSO (large_send).
> With the new hw_features it does not work to keep the old sysfs
> interface in parallel. Convert options.checksum_type to new hw_features.
[...]
> @@ -1482,32 +1476,28 @@ static int qeth_l3_start_ipa_checksum(st
[...]
> - rc = qeth_l3_send_checksum_command(card);
> - if (!rc)
> - dev_info(&card->gdev->dev,
> + card->dev->hw_features &= ~IPA_INBOUND_CHECKSUM;
> + card->dev->features &= ~IPA_INBOUND_CHECKSUM;
> + return 0;
> + }
Should be NETIF_F_RXCSUM probably.
Don't modify hw_features. Limit currently available features in
ndo_fix_features callback instead when checksumming is (temporarily)
unavailable.
[...]
> static int qeth_l3_set_features(struct net_device *dev, u32 features)
> {
> - enum qeth_checksum_types csum_type;
> struct qeth_card *card = dev->ml_priv;
> u32 changed = dev->features ^ features;
> + int on;
>
> if (!(changed & NETIF_F_RXCSUM))
> return 0;
>
> if (features & NETIF_F_RXCSUM)
> - csum_type = HW_CHECKSUMMING;
> + on = 1;
> else
> - csum_type = SW_CHECKSUMMING;
> + on = 0;
>
> dev->features = features ^ NETIF_F_RXCSUM;
> - return qeth_l3_set_rx_csum(card, csum_type);
> + return qeth_l3_set_rx_csum(card, on);
> }
Since you removed dev->features update from qeth_l3_set_rx_csum(), you
should also modify this code to match. On exit from ndo_fix_features,
dev->features should reflect what is currently set, even if part of
the request failed.
> static const struct ethtool_ops qeth_l3_ethtool_ops = {
> @@ -3342,6 +3326,12 @@ static int qeth_l3_setup_netdev(struct q
> if (!(card->info.unique_id & UNIQUE_ID_NOT_BY_CARD))
> card->dev->dev_id = card->info.unique_id &
> 0xffff;
> + if (!card->info.guestlan) {
> + card->dev->hw_features = NETIF_F_SG |
> + NETIF_F_RXCSUM | NETIF_F_IP_CSUM |
> + NETIF_F_TSO;
> + card->dev->features = NETIF_F_RXCSUM;
> + }
All features except RXCSUM will be disabled by default. Is that the intent here?
Best Regards,
Michał Mirosław
^ permalink raw reply
* Re: Fw: oops during unregister_netdevice interface enslaved to bond - regression
From: Frank Blaschka @ 2011-05-10 13:14 UTC (permalink / raw)
To: Eric Dumazet; +Cc: davem, netdev, ELELUECK
In-Reply-To: <1305017672.2614.9.camel@edumazet-laptop>
On Tue, May 10, 2011 at 10:54:32AM +0200, Eric Dumazet wrote:
> Le mardi 10 mai 2011 à 10:17 +0200, Einar EL Lueck a écrit :
> > Hi Dave,
> >
> > Einar EL Lueck/Germany/IBM wrote on 04/29/2011 04:45:45 PM:
> >
> > > From:
> > >
> > > Einar EL Lueck/Germany/IBM
> > >
> > > To:
> > >
> > > opurdila@ixiacom.com, netdev@vger.kernel.org, linux-
> > > s390@vger.kernel.org, davem@davemloft.net
> > >
> > > Cc:
> > >
> > > Frank Blaschka/Germany/IBM@IBMDE
> > >
> > > Date:
> > >
> > > 04/29/2011 04:45 PM
> > >
> > > Subject:
> > >
> > > Re: oops during unregister_netdevice interface enslaved to bond -
> > regression
> > >
> > > Hi Octavian,
> > >
> > > On 04/15/2011 10:53 AM, Frank Blaschka wrote:
> > > > Hi Octavian,
> > > >
> > > > your commit 443457242beb6716b43db4d62fe148eab5515505 introduced
> > > this regression.
> > > > I have reviewed the net device unregister code but did not
> > > understand it very well.
> > > > I have seen the problem only in combination with bonding. Can you
> > > give me some help
> > > > how to go on with this problem. I can reproduced it very easy on
> > asingle CPU
> > > > machine.
> > > >
> > >
> > > In this case rollback_registered_many iterates over the list of devs
> > > that initially has just one device in it. In a loop it calls
> > > call_netdevice_notifiers(NETDEV_UNREGISTER, dev) which triggers the
> > > bonding driver to call dev_close_many for the same device. That call
> > > to dev_close_many leads to the addition of the same device to the
> > > list over which rollback_registered_many is iterating. Consequently,
> > > netdev_unregister_kobject(dev) is called twice for the same device.
> > > Frank captured the result in his mail.
> > >
> >
> > Calls to the *_many functions introduced by Octavian may never interleave
> > because
> > the traversed lists modify each other. This was the root cause for the
> > symptom that Frank discovered. Octavian is not a valid mail recipient
> > anymore and did not react from any new mail address. I suggest to revert
> > the commit.
> >
>
> Hello Einar
>
> I am currently working on this stuff [adding even more batching and
> probably bugs as well ], so instead of revert I'll try to find a way to
> fix this.
>
great Thx!
> If you already have a script to reproduce the bug on virtual devices on
> x86 (not on s390 machines I dont have ;) ), I'll appreciate having a
> copy of it.a
I just checked todays net-next tree, problem is still there.
I don't have an x86 box, but I was able to reproduce the problem
with the dummy device (on s/390)
# modprobe bonding
# modprobe dummy
# ifconfig bond0 up
# ifenslave bond0 dummy0
# rmmod dummy
oops looks very much the same as unsing a real device. Hope this helps ...
>
> Thanks for the reminder.
>
> --
> 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
* [PATCH 3/3] RFC gianfar: add rx_ntuple feature
From: Sebastian.Poehn @ 2011-05-10 12:55 UTC (permalink / raw)
To: netdev
This is the main part. Functionality to add and remove ntuples, conversion from ntuple to hardware binary rx filer format, optimization of hardware filer table entries and extended hardware capability check.
--- gianfar_ethtool.c.orig 2011-05-10 11:45:33.301745000 +0200
+++ gianfar_ethtool.c 2011-05-10 13:27:23.041744819 +0200
@@ -42,6 +42,8 @@
extern void gfar_start(struct net_device *dev);
extern int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit);
+extern void sort(void *, size_t, size_t, int(*cmp_func)(const void *,
+ const void *), void(*swap_func)(void *, void *, int size));
#define GFAR_MAX_COAL_USECS 0xffff
#define GFAR_MAX_COAL_FRAMES 0xff
@@ -787,6 +789,1011 @@ static int gfar_set_nfc(struct net_devic
return ret;
}
+/*Global pointer on table*/
+struct filer_table *ref;
+u32 filer_index;
+struct interf *queue;
+
+enum nop {
+ ASC = 0, DESC = 1
+} row;
+
+static inline void toggle_order(void)
+{
+ row ^= 1;
+}
+
+static int my_comp(const void *a, const void *b)
+{
+
+ signed int temp;
+ if (*(u32 *) a > *(u32 *) b)
+ temp = -1;
+ else if (*(u32 *) a == *(u32 *) b)
+ temp = 0;
+ else
+ temp = 1;
+
+ if (row == DESC)
+ return temp;
+ else
+ return -temp;
+}
+
+static void my_swap(void *a, void *b, int size)
+{
+ u32 t1 = *(u32 *) a;
+ u32 t2 = *(u32 *) (a + 4);
+ u32 t3 = *(u32 *) (a + 8);
+ u32 t4 = *(u32 *) (a + 12);
+ *(u32 *) a = *(u32 *) b;
+ *(u32 *) (a + 4) = *(u32 *) (b + 4);
+ *(u32 *) (a + 8) = *(u32 *) (b + 8);
+ *(u32 *) (a + 12) = *(u32 *) (b + 12);
+ *(u32 *) b = t1;
+ *(u32 *) (b + 4) = t2;
+ *(u32 *) (b + 8) = t3;
+ *(u32 *) (b + 12) = t4;
+}
+
+/*Write a mask to hardware*/
+static inline void set_mask(u32 mask)
+{
+ ref->fe[filer_index].ctrl = RQFCR_AND | RQFCR_PID_MASK
+ | RQFCR_CMP_EXACT;
+ ref->fe[filer_index].prop = mask;
+ filer_index++;
+}
+
+/*Sets parse bits (e.g. IP or TCP)*/
+static void set_parse_bits(u32 host, u32 mask)
+{
+ set_mask(mask);
+ ref->fe[filer_index].ctrl = RQFCR_CMP_EXACT | RQFCR_PID_PARSE
+ | RQFCR_AND;
+ ref->fe[filer_index].prop = host;
+ filer_index++;
+}
+
+/*For setting a tuple of host,mask of type flag
+ *Example:
+ *IP-Src = 10.0.0.0/255.0.0.0
+ *host: 0x0A000000 mask: FF000000 flag: RQFPR_IPV4
+ *Note:
+ *For better usage of hardware 16 and 8 bit masks should be filled up
+ *with ones*/
+static void set_attribute(unsigned int host, unsigned int mask,
+ unsigned int flag)
+{
+ if (host || ~mask) {
+ /*This is to deal with masks smaller than 32bit
+ * and for special processing of MAC-filtering and
+ * VLAN-filtering*/
+ switch (flag) {
+ /*3bit*/
+ case RQFCR_PID_PRI:
+ if (((host & 0x7) == 0) && ((mask & 0x7) == 0))
+ return;
+ host &= 0x7;
+ break;
+ /*8bit*/
+ case RQFCR_PID_L4P:
+ case RQFCR_PID_TOS:
+ if (!(mask & 0xFF))
+ mask = 0xFFFFFFFF;
+ break;
+ /*12bit*/
+ case RQFCR_PID_VID:
+ if (((host & 0xFFF) == 0) && ((mask & 0xFFF) == 0))
+ return;
+ host &= 0xFFF;
+ break;
+ /*16bit*/
+ case RQFCR_PID_DPT:
+ case RQFCR_PID_SPT:
+ case RQFCR_PID_ETY:
+ if (!(mask & 0xFFFF))
+ mask = 0xFFFFFFFF;
+ break;
+ /*24bit*/
+ case RQFCR_PID_DAH:
+ case RQFCR_PID_DAL:
+ case RQFCR_PID_SAH:
+ case RQFCR_PID_SAL:
+ host &= 0x00FFFFFF;
+ break;
+ /*for all real 32bit masks*/
+ default:
+ if (!mask)
+ mask = 0xFFFFFFFF;
+ break;
+ }
+
+ set_mask(mask);
+ ref->fe[filer_index].ctrl = RQFCR_CMP_EXACT | RQFCR_AND | flag;
+ ref->fe[filer_index].prop = host;
+ filer_index++;
+ }
+}
+
+/*Translates host and mask for UDP,TCP or SCTP*/
+static void set_basic_ip(struct ethtool_tcpip4_spec *host,
+ struct ethtool_tcpip4_spec *mask)
+{
+ set_attribute(host->ip4src, mask->ip4src, RQFCR_PID_SIA);
+ set_attribute(host->ip4dst, mask->ip4dst, RQFCR_PID_DIA);
+ set_attribute(host->pdst, mask->pdst | 0xFFFF0000, RQFCR_PID_DPT);
+ set_attribute(host->psrc, mask->psrc | 0xFFFF0000, RQFCR_PID_SPT);
+ set_attribute(host->tos, mask->tos | 0xFFFFFF00, RQFCR_PID_TOS);
+}
+
+/*Translates host and mask for USER-IP4*/
+static inline void set_user_ip(struct ethtool_usrip4_spec *host,
+ struct ethtool_usrip4_spec *mask)
+{
+
+ set_attribute(host->ip4src, mask->ip4src, RQFCR_PID_SIA);
+ set_attribute(host->ip4dst, mask->ip4dst, RQFCR_PID_DIA);
+ set_attribute(host->tos, mask->tos | 0xFFFFFF00, RQFCR_PID_TOS);
+ set_attribute(host->proto, mask->proto | 0xFFFFFF00, RQFCR_PID_L4P);
+ set_attribute(host->l4_4_bytes, mask->l4_4_bytes, RQFCR_PID_ARB);
+
+}
+
+/*Translates host and mask for ETHER spec*/
+static inline void set_ether(struct ethhdr *host, struct ethhdr *mask)
+{
+ u32 upper_temp_mask = 0;
+ u32 lower_temp_mask = 0;
+ /*Source address*/
+ if (!(is_zero_ether_addr(host->h_source) && is_broadcast_ether_addr(
+ mask->h_source))) {
+ if (is_zero_ether_addr(mask->h_source)) {
+ upper_temp_mask = 0xFFFFFFFF;
+ lower_temp_mask = 0xFFFFFFFF;
+ } else {
+ upper_temp_mask = mask->h_source[0] << 16
+ | mask->h_source[1] << 8
+ | mask->h_source[2] | 0xFF000000;
+ lower_temp_mask = mask->h_source[3] << 16
+ | mask->h_source[4] << 8
+ | mask->h_source[5] | 0xFF000000;
+ }
+ /*Upper 24bit*/
+ set_attribute(0x80000000 | host->h_source[0] << 16
+ | host->h_source[1] << 8 | host->h_source[2],
+ upper_temp_mask, RQFCR_PID_SAH);
+ /*And the same for the lower part*/
+ set_attribute(0x80000000 | host->h_source[3] << 16
+ | host->h_source[4] << 8 | host->h_source[5],
+ lower_temp_mask, RQFCR_PID_SAL);
+ }
+ /*Destination address*/
+ if (!(is_zero_ether_addr(host->h_dest) && is_broadcast_ether_addr(
+ mask->h_dest))) {
+
+ /*Special for destination is limited broadcast*/
+ if ((is_broadcast_ether_addr(host->h_dest)
+ && is_zero_ether_addr(mask->h_dest))) {
+ set_parse_bits(RQFPR_EBC, RQFPR_EBC);
+ } else {
+
+ if (is_zero_ether_addr(mask->h_dest)) {
+ upper_temp_mask = 0xFFFFFFFF;
+ lower_temp_mask = 0xFFFFFFFF;
+ } else {
+ upper_temp_mask = mask->h_dest[0] << 16
+ | mask->h_dest[1] << 8
+ | mask->h_dest[2] | 0xFF000000;
+ lower_temp_mask = mask->h_dest[3] << 16
+ | mask->h_dest[4] << 8
+ | mask->h_dest[5] | 0xFF000000;
+ }
+
+ /*Upper 24bit*/
+ set_attribute(0x80000000 | host->h_dest[0] << 16
+ | host->h_dest[1] << 8
+ | host->h_dest[2], upper_temp_mask,
+ RQFCR_PID_DAH);
+ /*And the same for the lower part*/
+ set_attribute(0x80000000 | host->h_dest[3] << 16
+ | host->h_dest[4] << 8
+ | host->h_dest[5], lower_temp_mask,
+ RQFCR_PID_DAL);
+ }
+ }
+
+ /*Set Ethertype*/
+ if ((host->h_proto || ~(mask->h_proto | 0xFFFF0000))) {
+ set_attribute(host->h_proto, mask->h_proto | 0xFFFF0000,
+ RQFCR_PID_ETY);
+ }
+
+ /*
+ * Question: What the hell does the 0x80000000 do?
+ * Answer: It is just a dirty hack to prevent the setAtribute()
+ * to ignore a half MAC address which is like 0x000000/0xFFFFFF
+ */
+
+}
+
+/*For debugging*/
+void print_hw(struct gfar_private *p)
+{
+
+ int i = 0;
+ unsigned int a, b;
+ printk(KERN_DEBUG "No. Control Properties\n");
+ for (i = 0; i < 25; i++) {
+ gfar_read_filer(p, i, &a, &b);
+ printk(KERN_DEBUG "%3d %08x %08x\n", i, a, b);
+ }
+ printk(KERN_DEBUG "Data on hardware: %d\n", filer_index);
+}
+
+/*Copy size filer entries*/
+static inline void copy_filer_entries(struct filer_entry dst[0],
+ struct filer_entry src[0], s32 size)
+{
+ while (size > 0) {
+ size--;
+ dst[size].ctrl = src[size].ctrl;
+ dst[size].prop = src[size].prop;
+ }
+}
+
+/*Delete the contents of the filer-table between start and end
+ * and collapse them*/
+static int trim_filer_entries(int begin, int end)
+{
+ int length;
+ if (end > MAX_FILER_CACHE_IDX || begin > MAX_FILER_CACHE_IDX || begin
+ < 0 || end < 0 || end < begin)
+ return -EOUTOFRANGE;
+
+ length = (end - begin) + 1;
+
+ end++;
+
+ /*Copy*/
+ while (end < filer_index) {
+ ref->fe[begin].ctrl = ref->fe[end].ctrl;
+ ref->fe[begin++].prop = ref->fe[end++].prop;
+
+ }
+ /*Fill up with don't cares*/
+ while (begin <= filer_index) {
+ ref->fe[begin].ctrl = 0x60;
+ ref->fe[begin].prop = 0xFFFFFFFF;
+ begin++;
+ }
+
+ filer_index -= length;
+ return 0;
+}
+
+/*Make space on the wanted location*/
+static inline int expand_filer_entries(int begin, int length)
+{
+ int i = 0;
+ if (begin < 0 || length <= 0 || length + filer_index
+ > MAX_FILER_CACHE_IDX || begin > MAX_FILER_CACHE_IDX)
+ return -EOUTOFRANGE;
+
+ /*Copy*/
+ copy_filer_entries(&(ref->fe[begin + length]), &(ref->fe[begin]),
+ filer_index - length + 1);
+
+ /*Fill up with zeros*/
+ i = length;
+ while (i > 0) {
+ ref->fe[i + begin].ctrl = 0;
+ ref->fe[i + begin].prop = 0;
+ i--;
+ }
+
+ filer_index += length;
+ return 0;
+}
+
+/*Convert a ethtool_rx_ntuple to binary filter format of gianfar*/
+static inline int convert_to_filer(struct ethtool_rx_ntuple_flow_spec *rule)
+{
+
+ u32 vlan = 0, vlan_mask = 0;
+ u32 cfi = 0, cfi_mask = 0;
+ u32 prio = 0, prio_mask = 0;
+ u32 id = 0, id_mask = 0;
+
+ u32 old_index = filer_index;
+
+ /*Check if vlan is wanted*/
+ if (rule->vlan_tag != 0 || rule->vlan_tag_mask != 0xFFFF) {
+ if (rule->vlan_tag_mask == 0)
+ rule->vlan_tag_mask = 0xFFFF;
+
+ vlan = RQFPR_VLN;
+ vlan_mask = RQFPR_VLN;
+
+ /*Seperate the fields*/
+ cfi = (rule->vlan_tag >> 12) & 1;
+ cfi_mask = (rule->vlan_tag_mask >> 12) & 1;
+ id = rule->vlan_tag & 0xFFF;
+ id_mask = rule->vlan_tag_mask & 0xFFF;
+ prio = (rule->vlan_tag >> 13) & 0x7;
+ prio_mask = (rule->vlan_tag_mask >> 13) & 0x7;
+
+ if (cfi == 1 && cfi_mask == 1) {
+ vlan |= RQFPR_CFI;
+ vlan_mask |= RQFPR_CFI;
+ } else if (cfi == 0 && cfi_mask == 1) {
+ vlan_mask |= RQFPR_CFI;
+ }
+ }
+
+ switch (rule->flow_type) {
+ case TCP_V4_FLOW:
+ set_parse_bits(RQFPR_IPV4 | RQFPR_TCP | vlan, RQFPR_IPV4
+ | RQFPR_TCP | vlan_mask);
+ set_basic_ip((struct ethtool_tcpip4_spec *) &rule->h_u,
+ (struct ethtool_tcpip4_spec *) &rule->m_u);
+
+ break;
+ case UDP_V4_FLOW:
+ set_parse_bits(RQFPR_IPV4 | RQFPR_UDP | vlan, RQFPR_IPV4
+ | RQFPR_UDP | vlan_mask);
+ set_basic_ip((struct ethtool_tcpip4_spec *) &rule->h_u,
+ (struct ethtool_tcpip4_spec *) &rule->m_u);
+ break;
+ case SCTP_V4_FLOW:
+ set_parse_bits(RQFPR_IPV4 | vlan, RQFPR_IPV4 | vlan_mask);
+ set_attribute(132, 0xFFFFFFFF, RQFCR_PID_L4P);
+ set_basic_ip((struct ethtool_tcpip4_spec *) &rule->h_u,
+ (struct ethtool_tcpip4_spec *) &rule->m_u);
+ break;
+ case IP_USER_FLOW:
+ set_parse_bits(RQFPR_IPV4 | vlan, RQFPR_IPV4 | vlan_mask);
+ set_user_ip((struct ethtool_usrip4_spec *) &rule->h_u,
+ (struct ethtool_usrip4_spec *) &rule->m_u);
+ break;
+ case ETHER_FLOW:
+ if (vlan != 0)
+ set_parse_bits(vlan, vlan_mask);
+
+ set_ether((struct ethhdr *) &rule->h_u,
+ (struct ethhdr *) &rule->m_u);
+ break;
+ default:
+ return -1;
+ }
+
+ /*Set the vlan attributes in the end*/
+ if (vlan != 0) {
+ set_attribute(0x80000000 | id, 0xFFFFF000 | id_mask,
+ RQFCR_PID_VID);
+ set_attribute(0x80000000 | prio, 0xFFFFFFF8 | prio_mask,
+ RQFCR_PID_PRI);
+ }
+
+ /*If there has been nothing written till now, it must be a default*/
+ if (filer_index == old_index) {
+ set_mask(0xFFFFFFFF);
+ ref->fe[filer_index].ctrl = 0x20;
+ ref->fe[filer_index].prop = 0x0;
+ filer_index++;
+ }
+
+ /*Remove last AND*/
+ ref->fe[filer_index - 1].ctrl = ref->fe[filer_index - 1].ctrl
+ & (~RQFCR_AND);
+
+ /*Specify which queue to use or to drop*/
+ if (rule->action == ETHTOOL_RXNTUPLE_ACTION_DROP)
+ ref->fe[filer_index - 1].ctrl |= RQFCR_RJE;
+ else
+ ref->fe[filer_index - 1].ctrl |= (rule->action << 10);
+
+ /*Only big enough entries can be clustered*/
+ if (old_index + 2 < filer_index) {
+ ref->fe[old_index + 1].ctrl |= RQFCR_CLE;
+ ref->fe[filer_index - 1].ctrl |= RQFCR_CLE;
+ }
+
+ if (filer_index > MAX_FILER_CACHE_IDX - 1)
+ return -ESWFULL;
+
+ return 0;
+
+}
+
+/*Synchronizes the bitpattern from software buffers to hardware registers*/
+static int write_filer_to_hw(struct gfar_private *priv)
+{
+ s32 i = 0;
+ if (filer_index > MAX_FILER_IDX - 1)
+ return -EHWFULL;
+
+ /*Avoid inconsistent filer table*/
+ lock_rx_qs(priv);
+
+ for (; i < MAX_FILER_IDX - 1; i++)
+ gfar_write_filer(priv, i, ref->fe[i].ctrl, ref->fe[i].prop);
+
+ /*Last entry must be default accept
+ * because that is what people expect*/
+ gfar_write_filer(priv, i, 0x20, 0x0);
+
+ unlock_rx_qs(priv);
+
+ return 0;
+}
+
+/*Fill table with fall-troughs*/
+static inline void init_hw(void)
+{
+ int i = 0;
+
+ for (i = 0; i < MAX_FILER_CACHE_IDX; i++) {
+ ref->fe[i].ctrl = 0x60;
+ ref->fe[i].prop = 0xFFFFFFFF;
+ }
+}
+
+int add_table_entry(struct ethtool_rx_ntuple_flow_spec *flow)
+{
+ struct ethtool_rx_ntuple_flow_spec_container *temp;
+ temp = kmalloc(sizeof(struct ethtool_rx_ntuple_flow_spec_container),
+ GFP_KERNEL);
+ if (temp == NULL)
+ return -ENOMEM;
+ memcpy(&temp->fs, flow, sizeof(struct ethtool_rx_ntuple_flow_spec));
+ list_add_tail(&temp->list, &queue->ntuple_list.list);
+ queue->ntuple_list.count++;
+
+ if ((flow->data != 0) || (flow->data_mask != ~0))
+ printk(KERN_WARNING "User-data is not supported!\n");
+ if (flow->flow_type == IP_USER_FLOW)
+ if ((flow->h_u.usr_ip4_spec.ip_ver != 0)
+ || (flow->m_u.usr_ip4_spec.ip_ver != 255))
+ printk(KERN_WARNING "IP-Version is not supported!\n");
+ if (flow->flow_type == ETHER_FLOW)
+ if ((is_broadcast_ether_addr(flow->h_u.ether_spec.h_dest)
+ && is_zero_ether_addr(
+ flow->m_u.ether_spec.h_dest)))
+ printk(KERN_DEBUG
+ "Filtering broadcast is very cheap!\n");
+
+ return 0;
+
+}
+/*Compares flow-specs a and b and returns 0 if their are the same*/
+static int compare_flow_spec(struct ethtool_rx_ntuple_flow_spec *a,
+ struct ethtool_rx_ntuple_flow_spec *b)
+{
+
+ if (a == 0 || b == 0)
+ return -1;
+ /*if(ref->fe[i].fs->action!=b->action) goto next ;*/
+ /*if(ref->fe[i].fs->data!=b->data) goto next ;*/
+ /*if(ref->fe[i].fs->data_mask!=b->data_mask) goto next ;*/
+ if (a->flow_type != b->flow_type)
+ return 1;
+ if (a->vlan_tag != b->vlan_tag)
+ return 1;
+ if (a->vlan_tag_mask != b->vlan_tag_mask)
+ return 1;
+ switch (a->flow_type) {
+ case TCP_V4_FLOW:
+ case UDP_V4_FLOW:
+ case SCTP_V4_FLOW:
+ if (a->h_u.tcp_ip4_spec.ip4dst != b->h_u.tcp_ip4_spec.ip4dst)
+ return 1;
+ if (a->h_u.tcp_ip4_spec.ip4src != b->h_u.tcp_ip4_spec.ip4src)
+ return 1;
+ if (a->h_u.tcp_ip4_spec.pdst != b->h_u.tcp_ip4_spec.pdst)
+ return 1;
+ if (a->h_u.tcp_ip4_spec.psrc != b->h_u.tcp_ip4_spec.psrc)
+ return 1;
+ if (a->h_u.tcp_ip4_spec.tos != b->h_u.tcp_ip4_spec.tos)
+ return 1;
+ if (a->m_u.tcp_ip4_spec.ip4dst != b->m_u.tcp_ip4_spec.ip4dst)
+ return 1;
+ if (a->m_u.tcp_ip4_spec.ip4src != b->m_u.tcp_ip4_spec.ip4src)
+ return 1;
+ if (a->m_u.tcp_ip4_spec.pdst != b->m_u.tcp_ip4_spec.pdst)
+ return 1;
+ if (a->m_u.tcp_ip4_spec.psrc != b->m_u.tcp_ip4_spec.psrc)
+ return 1;
+ if (a->m_u.tcp_ip4_spec.tos != b->m_u.tcp_ip4_spec.tos)
+ return 1;
+ break;
+ case IP_USER_FLOW:
+ if (a->h_u.usr_ip4_spec.ip4dst != b->h_u.usr_ip4_spec.ip4dst)
+ return 1;
+ if (a->h_u.usr_ip4_spec.ip4src != b->h_u.usr_ip4_spec.ip4src)
+ return 1;
+ if (a->h_u.usr_ip4_spec.proto != b->h_u.usr_ip4_spec.proto)
+ return 1;
+ if (a->h_u.usr_ip4_spec.ip_ver != b->h_u.usr_ip4_spec.ip_ver)
+ return 1;
+ if (a->h_u.usr_ip4_spec.tos != b->h_u.usr_ip4_spec.tos)
+ return 1;
+ if (a->h_u.usr_ip4_spec.l4_4_bytes
+ != b->h_u.usr_ip4_spec.l4_4_bytes)
+ return 1;
+ if (a->m_u.usr_ip4_spec.ip4dst != b->m_u.usr_ip4_spec.ip4dst)
+ return 1;
+ if (a->m_u.usr_ip4_spec.ip4src != b->m_u.usr_ip4_spec.ip4src)
+ return 1;
+ if (a->m_u.usr_ip4_spec.proto != b->m_u.usr_ip4_spec.proto)
+ return 1;
+ if (a->m_u.usr_ip4_spec.ip_ver != b->m_u.usr_ip4_spec.ip_ver)
+ return 1;
+ if (a->m_u.usr_ip4_spec.tos != b->m_u.usr_ip4_spec.tos)
+ return 1;
+ if (a->m_u.usr_ip4_spec.l4_4_bytes
+ != b->m_u.usr_ip4_spec.l4_4_bytes)
+ return 1;
+ break;
+ case AH_V4_FLOW:
+ case ESP_V4_FLOW:
+ if (a->h_u.ah_ip4_spec.ip4dst != b->h_u.ah_ip4_spec.ip4dst)
+ return 1;
+ if (a->h_u.ah_ip4_spec.ip4src != b->h_u.ah_ip4_spec.ip4src)
+ return 1;
+ if (a->h_u.ah_ip4_spec.spi != b->h_u.ah_ip4_spec.spi)
+ return 1;
+ if (a->h_u.ah_ip4_spec.tos != b->h_u.ah_ip4_spec.tos)
+ return 1;
+ if (a->m_u.ah_ip4_spec.ip4dst != b->m_u.ah_ip4_spec.ip4dst)
+ return 1;
+ if (a->m_u.ah_ip4_spec.ip4src != b->m_u.ah_ip4_spec.ip4src)
+ return 1;
+ if (a->m_u.ah_ip4_spec.spi != b->m_u.ah_ip4_spec.spi)
+ return 1;
+ if (a->m_u.ah_ip4_spec.tos != b->m_u.ah_ip4_spec.tos)
+ return 1;
+ break;
+ case ETHER_FLOW:
+ if (compare_ether_addr(a->h_u.ether_spec.h_dest,
+ b->h_u.ether_spec.h_dest))
+ return 1;
+ if (compare_ether_addr(a->h_u.ether_spec.h_source,
+ b->h_u.ether_spec.h_source))
+ return 1;
+ if (compare_ether_addr(a->m_u.ether_spec.h_dest,
+ b->m_u.ether_spec.h_dest))
+ return 1;
+ if (compare_ether_addr(a->m_u.ether_spec.h_source,
+ b->m_u.ether_spec.h_source))
+ return 1;
+ if (a->h_u.ether_spec.h_proto != b->h_u.ether_spec.h_proto)
+ return 1;
+ if (a->m_u.ether_spec.h_proto != b->m_u.ether_spec.h_proto)
+ return 1;
+ break;
+ default:
+ return 1;
+ }
+
+ return 0;
+}
+
+/*Searches the existing flow_specs for flow and return NULL if none found
+ * or the address of the container in the linked list in case of success*/
+struct ethtool_rx_ntuple_flow_spec_container *search_table_entry(
+ struct ethtool_rx_ntuple_flow_spec *flow)
+{
+ struct ethtool_rx_ntuple_flow_spec_container *loop;
+ list_for_each_entry(loop, &queue->ntuple_list.list, list) {
+ if (compare_flow_spec(flow, &loop->fs) == 0)
+ return loop;
+ }
+ return NULL;
+}
+
+int del_table_entry(struct ethtool_rx_ntuple_flow_spec_container *cont)
+{
+
+ kfree(&cont->fs);
+
+ list_del(&cont->list);
+
+ queue->ntuple_list.count--;
+
+ return 0;
+}
+
+static inline int get_next_cluster_start(int start)
+{
+ for (; (start < filer_index) && (start < MAX_FILER_CACHE_IDX - 1);
+ start++) {
+ if ((ref->fe[start].ctrl & (RQFCR_AND | RQFCR_CLE))
+ == (RQFCR_AND | RQFCR_CLE)) {
+ return start;
+ }
+ }
+ return -1;
+}
+
+static inline int get_next_cluster_end(int start)
+{
+ for (; (start < filer_index) && (start < MAX_FILER_CACHE_IDX - 1);
+ start++) {
+ if ((ref->fe[start].ctrl & (RQFCR_AND | RQFCR_CLE))
+ == (RQFCR_CLE))
+ return start;
+ }
+ return -1;
+}
+
+/*Uses hardwares clustering option to reduce
+* the number of filer table entries*/
+static inline void cluster(void)
+{
+ s32 i = -1, j, iend, jend;
+ /*Do regular clustering*/
+ while ((i = get_next_cluster_start(++i)) != -1) {
+ j = i;
+ while ((j = get_next_cluster_start(++j)) != -1) {
+ if (ref->fe[i].ctrl != ref->fe[j].ctrl)
+ break;
+ if (ref->fe[i].prop != ref->fe[j].prop)
+ break;
+ if (ref->fe[i - 1].ctrl != ref->fe[j - 1].ctrl)
+ break;
+ if (ref->fe[i - 1].prop != ref->fe[j - 1].prop)
+ break;
+ /*If we come here i and j are
+ *candidates for clustering!*/
+ iend = get_next_cluster_end(i);
+ jend = get_next_cluster_end(j);
+ if (jend == -1 || iend == -1)
+ break;
+ /*First we make some free space, where our cluster
+ * element should be. Then we copy it there and finally
+ * delete in from its old location.
+ */
+
+ if (expand_filer_entries(iend, (jend - j))
+ == -EOUTOFRANGE)
+ break;
+
+ copy_filer_entries(&(ref->fe[iend + 1]), &(ref->fe[jend
+ + 1]), jend - j);
+
+ if (trim_filer_entries(jend - 1, jend + (jend - j))
+ == -EOUTOFRANGE)
+ return;
+
+ /*Mask out cluster bit*/
+ ref->fe[iend].ctrl &= ~(RQFCR_CLE);
+
+ }
+ }
+}
+
+/*Swaps the 0xFF80 masked bits of a1<>a2 and b1<>b2*/
+static inline void swap_ff80_bits(struct filer_entry *a1,
+ struct filer_entry *a2, struct filer_entry *b1,
+ struct filer_entry *b2)
+{
+
+ u32 temp[4];
+ temp[0] = a1->ctrl & 0xFF80;
+ temp[1] = a2->ctrl & 0xFF80;
+ temp[2] = b1->ctrl & 0xFF80;
+ temp[3] = b2->ctrl & 0xFF80;
+
+ a1->ctrl &= ~0xFF80;
+ a2->ctrl &= ~0xFF80;
+ b1->ctrl &= ~0xFF80;
+ b2->ctrl &= ~0xFF80;
+
+ a1->ctrl |= temp[1];
+ a2->ctrl |= temp[0];
+ b1->ctrl |= temp[3];
+ b2->ctrl |= temp[2];
+
+}
+
+/*Reduces the number of masks needed in the filer table to save entries*/
+static int optimize_masks(void)
+{
+
+ struct filer_table *dubli;
+
+ struct and_entry *and_table;
+
+ u32 and_index = 0, block_index = 1, previous_mask = 0, i = 0, j = 0,
+ size = 0, start = 0, prev = 1;
+
+ u32 old_first, old_last, new_first, new_last;
+
+ s32 ret = 0;
+
+ /*We need a copy of the filer table because
+ * we want to change its order*/
+ dubli = kmalloc(sizeof(struct filer_table), GFP_KERNEL);
+ if (dubli == NULL)
+ return -ENOMEM;
+ memcpy(dubli, ref, sizeof(struct filer_table));
+
+ and_table = kzalloc(sizeof(struct and_entry)
+ * (MAX_FILER_CACHE_IDX / 2 + 1), GFP_KERNEL);
+ if (and_table == NULL) {
+ ret = -ENOMEM;
+ goto end;
+ }
+
+ /*Make a list consisting of masks values with their start and
+ * end of validity and block as idicator for parts belonging
+ * together (glued by ANDs)*/
+ for (i = 0; i < filer_index; i++) {
+
+ if ((ref->fe[i].ctrl & 0xF) == 0) {
+ and_table[and_index].mask = ref->fe[i].prop;
+ and_table[and_index].start = i;
+ and_table[and_index].block = block_index;
+ if (and_index >= 1)
+ and_table[and_index - 1].end = i - 1;
+ and_index++;
+ }
+ /*Cluster starts will be seperated because they should
+ * hold their position*/
+ if ((ref->fe[i].ctrl & RQFCR_CLE) == RQFCR_CLE)
+ block_index++;
+ /*A not set AND indicated the end of a depended block*/
+ if ((ref->fe[i].ctrl & RQFCR_AND) == 0)
+ block_index++;
+
+ }
+
+ and_table[and_index - 1].end = i - 1;
+
+ /*Now we can sort the table from above by the values of the masks.
+ * Important: The 0xFF80 flags of the first and last entry of a
+ * block must hold their position (which queue, CLE, RJE, AND)*/
+ for (i = 0; i < and_index; i++) {
+
+ if (prev != and_table[i].block) {
+ old_first = and_table[start].start + 1;
+ old_last = and_table[i - 1].end;
+ /*I my opinion start should be multiplied by
+ * sizeof(struct and_entry) do not ask me why
+ * only this version is working */
+ sort(and_table + start, size, sizeof(struct and_entry),
+ &my_comp, &my_swap);
+ /*Toggle order for every block. This makes the
+ * thing more efficient! Believe me!*/
+
+ toggle_order();
+
+ new_first = and_table[start].start + 1;
+ new_last = and_table[i - 1].end;
+
+ /*Thats the 0xFF80 swapping*/
+ swap_ff80_bits(&dubli->fe[new_first],
+ &dubli->fe[old_first],
+ &dubli->fe[new_last],
+ &dubli->fe[old_last]);
+
+ start = i;
+ size = 0;
+ }
+ size++;
+ prev = and_table[i].block;
+ }
+
+ /*Now we can copy the data from our duplicated filer table to
+ * the real one in the order the mask table says*/
+ for (i = 0; i < and_index; i++) {
+ size = and_table[i].end - and_table[i].start + 1;
+ copy_filer_entries(&(ref->fe[j]),
+ &(dubli->fe[and_table[i].start]), size);
+ j += size;
+ }
+
+ /*Silly duplicate checker: Drops identical masks*/
+
+ for (i = 0; i < filer_index && i < MAX_FILER_CACHE_IDX; i++) {
+ if (ref->fe[i].ctrl == 0x80) {
+ previous_mask = i++;
+ break;
+ }
+ }
+ for (; i < filer_index && i < MAX_FILER_CACHE_IDX; i++) {
+ if (ref->fe[i].ctrl == 0x80) {
+ if (ref->fe[i].prop == ref->fe[previous_mask].prop) {
+ /*Two identical ones found!
+ * So drop the second one!*/
+ trim_filer_entries(i, i);
+
+ } else
+ /*Not identical!*/
+ previous_mask = i;
+ }
+ }
+
+ kfree(and_table);
+end: kfree(dubli);
+ return ret;
+}
+
+int do_action(struct ethtool_rx_ntuple_flow_spec *flow,
+ struct gfar_private *priv)
+{
+ struct ethtool_rx_ntuple_flow_spec_container *loop_ptr;
+ s32 i = 0;
+ s32 ret = 0;
+ filer_index = 0;
+
+ /*Only temporary needed! The 20 additional
+ * entries are a shadow for one element*/
+ ref = kzalloc(sizeof(struct filer_table) + 20
+ * sizeof(struct filer_table), GFP_KERNEL);
+ if (ref == NULL) {
+ printk(KERN_WARNING "Can not get memory\n");
+ return -ENOMEM;
+ }
+
+ loop_ptr = search_table_entry(flow);
+
+ if (flow->action == ETHTOOL_RXNTUPLE_ACTION_CLEAR) {
+ if (loop_ptr != NULL)
+ del_table_entry(loop_ptr);
+ else {
+ printk(KERN_WARNING "Element not found!\n");
+ return -1;
+ }
+ } else {
+ if (loop_ptr != NULL) {
+ printk(KERN_WARNING "Element is already online!\n");
+ return -1;
+ }
+
+ }
+
+ /*Initializes the filer table with a default accept for all packets*/
+ init_hw();
+
+ /*Now convert the existing filer data from flow_spec into
+ * filer tables binary format*/
+ list_for_each_entry(loop_ptr, &queue->ntuple_list.list, list) {
+ ret = convert_to_filer(&loop_ptr->fs);
+ if (ret == -ESWFULL) {
+ printk(KERN_WARNING
+ "To much entries! Can not add! SW\n");
+ goto end;
+ }
+ }
+
+ /*Here add the new one*/
+ if (flow->action != ETHTOOL_RXNTUPLE_ACTION_CLEAR) {
+ ret = convert_to_filer(flow);
+ if (ret == -ESWFULL) {
+ printk(KERN_WARNING
+ "To much entries! Can not add! SW\n");
+ goto end;
+ }
+ if (ret == -1) {
+ printk(KERN_WARNING "Flow-type not supported!\n");
+ goto end;
+ }
+ }
+
+ i = filer_index;
+
+ /*Optimizations to save entries*/
+ cluster();
+ optimize_masks();
+
+ printk(KERN_DEBUG "\tSummary:\n"
+ "\tData on hardware: %d\n"
+ "\tCompression rate: %d %%\n", filer_index, 100 - (100 * filer_index)
+ / i);
+
+ /*Write everything to hardware*/
+ ret = write_filer_to_hw(priv);
+ if (ret == -EHWFULL) {
+ printk(KERN_WARNING "To much entries! Can not add! HW\n");
+ goto end;
+ }
+
+ /*Only if all worked fine, add the flow*/
+ if (flow->action != ETHTOOL_RXNTUPLE_ACTION_CLEAR)
+ add_table_entry(flow);
+
+end: kfree(ref);
+ return ret;
+}
+
+static struct interf *init_table(struct gfar_private *priv)
+{
+ struct gfar __iomem *regs = NULL;
+ int i;
+
+ regs = priv->gfargrp[0].regs;
+
+ /*Check if we are in FIFO mode*/
+ i = gfar_read(®s->ecntrl);
+ i &= ECNTRL_FIFM;
+ if (i == ECNTRL_FIFM) {
+ i = gfar_read(®s->rctrl);
+ i &= RCTRL_PRSDEP_MASK | RCTRL_PRSFM;
+ if (i == (RCTRL_PRSDEP_MASK | RCTRL_PRSFM)) {
+ printk(KERN_EMERG
+ "Interface in FIFO mode\n"
+ "Receive Queue Filtering enabled\n");
+ } else {
+ printk(KERN_EMERG
+ "Interface in FIFO mode\n"
+ "Receive Queue Filtering is disabled\n");
+ return (struct interf *)-1;
+ }
+ }
+ /*Or in standard mode*/
+ else{
+ i = gfar_read(®s->rctrl);
+ i &= RCTRL_PRSDEP_MASK;
+ if (i == RCTRL_PRSDEP_MASK) {
+ printk(KERN_EMERG
+ "Receive Queue Filtering enabled\n");
+ } else {
+ printk(KERN_EMERG
+ "Receive Queue Filtering is disabled\n");
+ return (struct interf *)-1;
+ }
+ }
+
+ /*Sets the properties for arbitrary filer rule
+ * to the first 4 Layer 4 Bytes*/
+ regs->rbifx = 0xC0C1C2C3;
+
+ queue = kzalloc(sizeof(struct interf), GFP_KERNEL);
+ INIT_LIST_HEAD(&(queue->ntuple_list.list));
+ queue->ntuple_list.count = 0;
+
+ return queue;
+
+}
+
+static int gfar_set_rx_ntuple(struct net_device *dev,
+ struct ethtool_rx_ntuple *cmd)
+{ struct gfar __iomem *regs = NULL;
+ struct gfar_private *priv = netdev_priv(dev);
+ int i = 0;
+ static struct interf *store[10];
+
+ regs = priv->gfargrp[0].regs;
+
+ /*Only values between -2 and num_rx_queues -1 allowed*/
+ if ((cmd->fs.action >= (signed int)priv->num_rx_queues) ||
+ (cmd->fs.action < ETHTOOL_RXNTUPLE_ACTION_CLEAR))
+ return -EINVAL;
+
+ for (i = 0; i < 10; i++) {
+ if (store[i] == 0) {
+ store[i] = init_table(priv);
+ if (store[i] == (struct interf *)-1) {
+ store[i] = 0;
+ return -1;
+ }
+ strcpy(store[i]->name, dev->name);
+ break;
+ } else if (!strcmp(store[i]->name, dev->name)) {
+ queue = store[i];
+ break;
+ }
+
+ }
+
+ do_action(&cmd->fs, priv);
+
+ return 0;
+}
+
+
const struct ethtool_ops gfar_ethtool_ops = {
.get_settings = gfar_gsettings,
.set_settings = gfar_ssettings,
@@ -808,4 +1815,6 @@ const struct ethtool_ops gfar_ethtool_op
.set_wol = gfar_set_wol,
#endif
.set_rxnfc = gfar_set_nfc,
+ /*function for accessing rx queue filer*/
+ .set_rx_ntuple = gfar_set_rx_ntuple
};
Signed-off-by: Sebastian Poehn <sebastian.poehn@belden.com>
DISCLAIMER:
Privileged and/or Confidential information may be contained in this
message. If you are not the addressee of this message, you may not
copy, use or deliver this message to anyone. In such event, you
should destroy the message and kindly notify the sender by reply
e-mail. It is understood that opinions or conclusions that do not
relate to the official business of the company are neither given
nor endorsed by the company.
Thank You.
^ permalink raw reply
* [PATCH 2/3] RFC gianfar: add rx_ntuple feature
From: Sebastian.Poehn @ 2011-05-10 12:54 UTC (permalink / raw)
To: netdev
This part sets the flags for ethtool and does primary hardware checking.
--- gianfar.c.orig 2011-05-10 11:08:13.573744000 +0200
+++ gianfar.c 2011-05-10 11:22:07.865744495 +0200
@@ -751,7 +751,8 @@ static int gfar_of_init(struct platform_
FSL_GIANFAR_DEV_HAS_VLAN |
FSL_GIANFAR_DEV_HAS_MAGIC_PACKET |
FSL_GIANFAR_DEV_HAS_EXTENDED_HASH |
- FSL_GIANFAR_DEV_HAS_TIMER;
+ FSL_GIANFAR_DEV_HAS_TIMER |
+ FSL_GIANFAR_DEV_HAS_RX_FILER;
ctype = of_get_property(np, "phy-connection-type", NULL);
@@ -1042,6 +1043,9 @@ static int gfar_probe(struct platform_de
if (priv->device_flags & FSL_GIANFAR_DEV_HAS_VLAN)
dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+ if (priv->device_flags & FSL_GIANFAR_DEV_HAS_RX_FILER)
+ dev->features |= NETIF_F_NTUPLE;
+
if (priv->device_flags & FSL_GIANFAR_DEV_HAS_EXTENDED_HASH) {
priv->extended_hash = 1;
priv->hash_width = 9;
@@ -1151,9 +1155,8 @@ static int gfar_probe(struct platform_de
priv->rx_queue[i]->rxic = DEFAULT_RXIC;
}
- /* enable filer if using multiple RX queues*/
- if(priv->num_rx_queues > 1)
- priv->rx_filer_enable = 1;
+ /* always enable rx filer*/
+ priv->rx_filer_enable = 1;
/* Enable most messages by default */
priv->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1;
Signed-off-by: Sebastian Poehn <sebastian.poehn@belden.com>
DISCLAIMER:
Privileged and/or Confidential information may be contained in this
message. If you are not the addressee of this message, you may not
copy, use or deliver this message to anyone. In such event, you
should destroy the message and kindly notify the sender by reply
e-mail. It is understood that opinions or conclusions that do not
relate to the official business of the company are neither given
nor endorsed by the company.
Thank You.
^ permalink raw reply
* Re: Fw: oops during unregister_netdevice interface enslaved to bond - regression
From: Eric Dumazet @ 2011-05-10 13:03 UTC (permalink / raw)
To: Einar EL Lueck; +Cc: davem, netdev, Frank Blaschka
In-Reply-To: <1305017959.2614.13.camel@edumazet-laptop>
Le mardi 10 mai 2011 à 10:59 +0200, Eric Dumazet a écrit :
> Le mardi 10 mai 2011 à 10:54 +0200, Eric Dumazet a écrit :
>
> > I am currently working on this stuff [adding even more batching and
> > probably bugs as well ], so instead of revert I'll try to find a way to
> > fix this.
> >
> > If you already have a script to reproduce the bug on virtual devices on
> > x86 (not on s390 machines I dont have ;) ), I'll appreciate having a
> > copy of it.
> >
> > Thanks for the reminder.
>
> BTW make sure latest linux-2.6 still exhibits the problem, we fixed some
> things after original Octavian commit
>
> List of commits :
>
> commit ceaaec98ad99859ac90ac6863ad0a6cd075d8e0e
> net: deinit automatic LIST_HEAD
>
> commit f87e6f47933e3ebeced9bb12615e830a72cedce4
> net: dont leave active on stack LIST_HEAD
>
>
OK I trigger the bug on linux-2.6 with :
modprobe bonding
ip link add testa type veth peer name testb
ifconfig bond0 up
ifenslave bond0 testa
ip link del testa
I'll cook a patch, stay tuned :)
^ permalink raw reply
* Re: Bug#625914: linux-image-2.6.38-2-amd64: bridging is not interacting well with multicast in 2.6.38-4
From: Yann Dupont @ 2011-05-10 12:55 UTC (permalink / raw)
To: Ben Hutchings; +Cc: netdev
In-Reply-To: <1305031369.4065.259.camel@localhost>
> On Mon, 2011-05-09 at 21:38 -0700, Noah Meyerhans wrote:
>> On Tue, May 10, 2011 at 03:38:44AM +0100, Ben Hutchings wrote:
>>> This is pretty weird. Debian version 2.6.38-3 has a few bridging
>>> changes from stable 2.6.38.3 and 2.6.38.4, but they don't look like they
>>> would cause this.
>> I have apparently filed the bug against the wrong version of Debian's
>> kernel. 2.6.38-3 is not affected, and works as expected. The change
>> was introduced in -4. That may have been clear from the report itself,
>> but the report was filed against -3. I've fixed that in the BTS.
> I gathered that, and then made the same mistake in writing the above!
> The version with the regression, 2.6.38-4, includes the changes from
> stable 2.6.38.3 and 2.6.38.4
>
> Ben.
>
>
We just hitted the very same problem yesterday, with debian too , BUT
with vanilla kernels (hand compiled from GIT, with a specific config).
I can confirm that 2.6.38.5 & 2.6.38.6 have this problem, but 2.6.38.3
works fine.
So this is not a debian specific bug as far as I can see.
Cheers,
--
Yann Dupont - Service IRTS, DSI Université de Nantes
Tel : 02.53.48.49.20 - Mail/Jabber : Yann.Dupont@univ-nantes.fr
^ permalink raw reply
* [PATCH 1/3] RFC gianfar: add rx_ntuple feature
From: Sebastian.Poehn @ 2011-05-10 12:53 UTC (permalink / raw)
To: netdev
Patches created against net-next-2.6!
This series implements the set_rx_ntuple feature for ethtool. Code is well tested and should be stable. Some code rework and better integration into gianfar_ethtool.c have to been done! Note that all rx flow hashing stuff on hardware will be overwritten!
This part extends some hardware bit-flags and adds some data structures for ntuple conversion and storage.
--- gianfar.h.orig 2011-05-10 11:26:43.113744000 +0200
+++ gianfar.h 2011-05-10 12:59:15.301744599 +0200
@@ -168,6 +168,7 @@ extern const char gfar_driver_version[];
#define MACCFG2_LENGTHCHECK 0x00000010
#define MACCFG2_MPEN 0x00000008
+#define ECNTRL_FIFM 0x00008000
#define ECNTRL_INIT_SETTINGS 0x00001000
#define ECNTRL_TBI_MODE 0x00000020
#define ECNTRL_REDUCED_MODE 0x00000010
@@ -271,6 +272,7 @@ extern const char gfar_driver_version[];
#define RCTRL_TUCSEN 0x00000100
#define RCTRL_PRSDEP_MASK 0x000000c0
#define RCTRL_PRSDEP_INIT 0x000000c0
+#define RCTRL_PRSFM 0x00000020
#define RCTRL_PROM 0x00000008
#define RCTRL_EMEN 0x00000002
#define RCTRL_REQ_PARSER (RCTRL_VLEX | RCTRL_IPCSEN | \
@@ -870,6 +872,7 @@ struct gfar {
#define FSL_GIANFAR_DEV_HAS_BD_STASHING 0x00000200
#define FSL_GIANFAR_DEV_HAS_BUF_STASHING 0x00000400
#define FSL_GIANFAR_DEV_HAS_TIMER 0x00000800
+#define FSL_GIANFAR_DEV_HAS_RX_FILER 0x00001000
#if (MAXGROUPS == 2)
#define DEFAULT_MAPPING 0xAA
@@ -1140,6 +1143,16 @@ static inline void gfar_write_filer(stru
gfar_write(®s->rqfpr, fpr);
}
+static inline void gfar_read_filer(struct gfar_private *priv,
+ unsigned int far, unsigned int *fcr, unsigned int *fpr)
+{
+ struct gfar __iomem *regs = priv->gfargrp[0].regs;
+
+ gfar_write(®s->rqfar, far);
+ *fcr = gfar_read(®s->rqfcr);
+ *fpr = gfar_read(®s->rqfpr);
+}
+
extern void lock_rx_qs(struct gfar_private *priv);
extern void lock_tx_qs(struct gfar_private *priv);
extern void unlock_rx_qs(struct gfar_private *priv);
@@ -1157,4 +1170,39 @@ int gfar_set_features(struct net_device
extern const struct ethtool_ops gfar_ethtool_ops;
+#define ESWFULL 160
+#define EHWFULL 161
+#define EOUTOFRANGE 162
+#define PRINT_MAX 100
+#define MAX_FILER_CACHE_IDX (2*(MAX_FILER_IDX))
+
+extern struct interf *queue;
+
+struct and_entry {
+ unsigned int mask; /*The mask value which is valid for a block with*/
+ unsigned int start; /*start*/
+ unsigned int end; /*till end*/
+ unsigned int block; /*Same block values indicate depended entries*/
+};
+
+/*For exactly one device*/
+struct interf {
+ struct ethtool_rx_ntuple_list ntuple_list;
+ char name[IFNAMSIZ]; /*Name from struct net_device*/
+};
+
+/*Table which represents a receive filer table entry */
+struct filer_entry {
+ u32 ctrl; /*The control field from HW*/
+ u32 prop; /*The property field from HW*/
+};
+
+/*Full table*/
+struct filer_table {
+ struct filer_entry fe[MAX_FILER_CACHE_IDX];
+};
+
+int do_action(struct ethtool_rx_ntuple_flow_spec *flow, struct gfar_private *p);
+
+
#endif /* __GIANFAR_H */
Signed-off-by: Sebastian Poehn <sebastian.poehn@belden.com>
DISCLAIMER:
Privileged and/or Confidential information may be contained in this
message. If you are not the addressee of this message, you may not
copy, use or deliver this message to anyone. In such event, you
should destroy the message and kindly notify the sender by reply
e-mail. It is understood that opinions or conclusions that do not
relate to the official business of the company are neither given
nor endorsed by the company.
Thank You.
^ permalink raw reply
* Re: Bug#625914: linux-image-2.6.38-2-amd64: bridging is not interacting well with multicast in 2.6.38-4
From: Ben Hutchings @ 2011-05-10 12:42 UTC (permalink / raw)
To: Noah Meyerhans; +Cc: 625914, netdev, bridge
In-Reply-To: <20110510043833.GG6397@morgul.net>
[-- Attachment #1: Type: text/plain, Size: 980 bytes --]
On Mon, 2011-05-09 at 21:38 -0700, Noah Meyerhans wrote:
> On Tue, May 10, 2011 at 03:38:44AM +0100, Ben Hutchings wrote:
> > This is pretty weird. Debian version 2.6.38-3 has a few bridging
> > changes from stable 2.6.38.3 and 2.6.38.4, but they don't look like they
> > would cause this.
>
> I have apparently filed the bug against the wrong version of Debian's
> kernel. 2.6.38-3 is not affected, and works as expected. The change
> was introduced in -4. That may have been clear from the report itself,
> but the report was filed against -3. I've fixed that in the BTS.
I gathered that, and then made the same mistake in writing the above!
The version with the regression, 2.6.38-4, includes the changes from
stable 2.6.38.3 and 2.6.38.4
Ben.
> I've also confirmed that -5 is affected, to no great surprise.
>
> I'll investigate further.
>
> noah
>
--
Ben Hutchings
Once a job is fouled up, anything done to improve it makes it worse.
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]
^ permalink raw reply
* Re: [PATCH] net/bonding: adjust codingstyle for bond_3ad files
From: Rafael Aquini @ 2011-05-10 12:22 UTC (permalink / raw)
To: Jay Vosburgh
Cc: kernel-janitors, David Miller, Joe Perches, Andy Gospodarek,
shemminger, netdev, Nicolas Kaiser
In-Reply-To: <23511.1304992840@death>
Howdy Jay,
On Mon, May 09, 2011 at 07:00:40PM -0700, Jay Vosburgh wrote:
> >@@ -644,9 +640,7 @@ static void __update_ntt(struct lacpdu *lacpdu, struct port *port)
> > */
> > static void __attach_bond_to_agg(struct port *port)
> > {
> >- port = NULL; /* just to satisfy the compiler */
> >- // This function does nothing since the parser/multiplexer of the receive
> >- // and the parser/multiplexer of the aggregator are already combined
> >+ port = NULL;
> > }
> >
> > /**
> >@@ -659,9 +653,7 @@ static void __attach_bond_to_agg(struct port *port)
> > */
> > static void __detach_bond_from_agg(struct port *port)
> > {
> >- port = NULL; /* just to satisfy the compiler */
> >- // This function does nothing sience the parser/multiplexer of the receive
> >- // and the parser/multiplexer of the aggregator are already combined
> >+ port = NULL;
>
> These two do-nothing functions should either
>
> a) be removed entirely, and their call site replaced with a
> comment explaining this variation on the standard (that we don't need
> the "Attach_Mux_To_Aggregator" or "Detach_Mux_From_Aggregator" functions
> specified in the standard for the "Mux machine state diagram"), or
>
> b) the comment needs to remain in some form to document this
> variation on the standard.
>
Those comments were stripped from the function bodies because they already are
present in their leading comment blocks. Leaving them there sounded to me just
like echoing the very same thing twice.
However, each one of those functions is just called once from ad_mux_machine(),
so it might be a better idea (and easy) to wipe them away -- following your
suggestion a); or we can just leave them there, turning them into inline
functions instead. What approach do you prefer?
All other notes and suggestions you provide me will be accomplished soon.
Thanks for keep providing valuable feedback.
Cheers!
--
Rafael Aquini <aquini@linux.com>
^ permalink raw reply
* Re: [Bugme-new] [Bug 33502] New: Caught 64-bit read from uninitialized memory in __alloc_skb
From: Vegard Nossum @ 2011-05-10 12:24 UTC (permalink / raw)
To: Pekka Enberg
Cc: Eric Dumazet, Christoph Lameter, casteyde.christian,
Andrew Morton, netdev, bugzilla-daemon, bugme-daemon
In-Reply-To: <4DC91137.4030109@cs.helsinki.fi>
On Tue, 10 May 2011 13:19:35 +0300, Pekka Enberg
<penberg@cs.helsinki.fi> wrote:
> On 5/10/11 1:17 PM, Eric Dumazet wrote:
>> Le mardi 10 mai 2011 à 13:03 +0300, Pekka Enberg a écrit :
>>
>>> Can't we fix the issue by putting kmemcheck_mark_initialized() to
>>> set_freepointer()?
>>
>> This would solve kmemcheck problem, not DEBUG_PAGEALLOC
>
> Oh, right. Christoph? We need to support DEBUG_PAGEALLOC with SLUB.
Hi,
Disclaimer: I don't know how the algorithm is supposed to work, so
please excuse me if this makes no sense at all. But here goes:
Presumably the problem is that the page can get freed, and that with
DEBUG_PAGEALLOC, the page will therefore not be present and subsequently
trigger a page fault when doing this cmpxchg() on the possibly freed
object.
Regardless of DEBUG_PAGEALLOC or kmemcheck, what happens if the page
gets freed, then allocated again for a completely different purpose in
another part of the kernel, and new user of the page by chance writes
the same "tid" number that the cmpxchg() is expecting?
I guess I'm asking: Are we relying on the fact that this has a
negligible probability of happening? Or did I just misunderstand what
the algorithm does, and it is in fact provable (in theory) that nothing
wrong can happen?
Thanks,
Vegard
^ permalink raw reply
* Re: [PATCH v4 1/1] can: add pruss CAN driver.
From: Subhasish Ghosh @ 2011-05-10 12:21 UTC (permalink / raw)
To: Alan Cox
Cc: sachi-EvXpCiN+lbve9wHmmfpqLFaTQe2KTcn/,
davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/,
Arnd Bergmann, Netdev-u79uwXL29TY76Z2rM5mHXA, nsekhar-l0cyMroinI0,
open list, CAN NETWORK DRIVERS, Marc Kleine-Budde,
Wolfgang Grandegger, m-watkins-l0cyMroinI0,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20110510112734.54160824-qBU/x9rampVanCEyBjwyrvXRex20P6io@public.gmane.org>
>> Yes, In case if we allow the ALL implementation, it hogs the CPU.
>> In that case we do not need the PRU. The whole purpose of the PRU
>> is to offload the processor for any such implementations.
>
> So the kernel presumably needs to switch between using the PRU and native
> according to the number of ids being requested at the time ?
All the IDs are programmed into the PRU data RAM.
The Kernel receives interrupts based upon these IDs.
I could not clearly follow "PRU and native", could you please elaborate.
> That would be roughly what we do with other things (eg IP multicast) so
> that apps don't need to know all the innards
^ permalink raw reply
* Confirm!!
From: santiani @ 2011-05-10 12:00 UTC (permalink / raw)
Your E-mail ID qualify you for a lump sum of 1.200,000,00 Pounds in the
Royal Dutch Online Programm.Send
your: Names,Country,Sex,Tel,Occupation
^ permalink raw reply
* RE: linux-next: manual merge of the net tree with the net-current tree
From: Sathya.Perla @ 2011-05-10 11:55 UTC (permalink / raw)
To: sfr; +Cc: linux-next, linux-kernel, Somnath.Kotur, davem, netdev
In-Reply-To: <20110510114917.11f8738f.sfr@canb.auug.org.au>
Hi Stephen, your conflict fix below looks fine. Thanks.
-Sathya
-----Original Message-----
From: Stephen Rothwell [mailto:sfr@canb.auug.org.au]
Sent: Tuesday, May 10, 2011 7:19 AM
To: David Miller; netdev@vger.kernel.org
Cc: linux-next@vger.kernel.org; linux-kernel@vger.kernel.org; Kotur, Somnath; Perla, Sathya
Subject: linux-next: manual merge of the net tree with the net-current tree
Hi all,
Today's linux-next merge of the net tree got a conflict in
drivers/net/benet/be_main.c between commit 6709d9521df0 ("be2net: Fixed
bugs related to PVID") from the net-current tree and commit 15d721847f56
("be2net: parse vid and vtm fields of rx-compl only if vlanf bit is set")
from the net tree.
I fixed it up (I think - see below) and can carry the fix as necessary.
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
diff --cc drivers/net/benet/be_main.c
index 9187fb4,7b19931..0000000
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@@ -1103,9 -1102,14 +1104,14 @@@ static void be_parse_rx_compl_v1(struc
AMAP_GET_BITS(struct amap_eth_rx_compl_v1, numfrags, compl);
rxcp->pkt_type =
AMAP_GET_BITS(struct amap_eth_rx_compl_v1, cast_enc, compl);
- rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vtm, compl);
- rxcp->vlan_tag = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vlan_tag,
- compl);
+ rxcp->rss_hash =
+ AMAP_GET_BITS(struct amap_eth_rx_compl_v1, rsshash, rxcp);
+ if (rxcp->vlanf) {
+ rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vtm,
+ compl);
- rxcp->vid = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vlan_tag,
++ rxcp->vlan_tag = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vlan_tag,
+ compl);
+ }
}
static void be_parse_rx_compl_v0(struct be_adapter *adapter,
@@@ -1130,9 -1134,14 +1136,14 @@@
AMAP_GET_BITS(struct amap_eth_rx_compl_v0, numfrags, compl);
rxcp->pkt_type =
AMAP_GET_BITS(struct amap_eth_rx_compl_v0, cast_enc, compl);
- rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vtm, compl);
- rxcp->vlan_tag = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vlan_tag,
- compl);
+ rxcp->rss_hash =
+ AMAP_GET_BITS(struct amap_eth_rx_compl_v0, rsshash, rxcp);
+ if (rxcp->vlanf) {
+ rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vtm,
+ compl);
- rxcp->vid = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vlan_tag,
++ rxcp->vlan_tag = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vlan_tag,
+ compl);
+ }
}
static struct be_rx_compl_info *be_rx_compl_get(struct be_rx_obj *rxo)
@@@ -1154,17 -1163,19 +1165,20 @@@
else
be_parse_rx_compl_v0(adapter, compl, rxcp);
- /* vlanf could be wrongly set in some cards. ignore if vtm is not set */
- if ((adapter->function_mode & 0x400) && !rxcp->vtm)
- rxcp->vlanf = 0;
+ if (rxcp->vlanf) {
+ /* vlanf could be wrongly set in some cards.
+ * ignore if vtm is not set */
+ if ((adapter->function_mode & 0x400) && !rxcp->vtm)
+ rxcp->vlanf = 0;
- if (!lancer_chip(adapter))
- rxcp->vlan_tag = swab16(rxcp->vlan_tag);
+ if (!lancer_chip(adapter))
- rxcp->vid = swab16(rxcp->vid);
++ rxcp->vlan_tag = swab16(rxcp->vlan_tag);
- if (((adapter->pvid & VLAN_VID_MASK) ==
- (rxcp->vlan_tag & VLAN_VID_MASK)) &&
- !adapter->vlan_tag[rxcp->vlan_tag])
- rxcp->vlanf = 0;
- if ((adapter->pvid == rxcp->vid) &&
- !adapter->vlan_tag[rxcp->vid])
++ if (((adapter->pvid & VLAN_VID_MASK) ==
++ (rxcp->vlan_tag & VLAN_VID_MASK)) &&
++ !adapter->vlan_tag[rxcp->vlan_tag])
+ rxcp->vlanf = 0;
+ }
/* As the compl has been parsed, reset it; we wont touch it again */
compl->dw[offsetof(struct amap_eth_rx_compl_v1, valid) / 32] = 0;
^ permalink raw reply
* Re: [Bugme-new] [Bug 33502] New: Caught 64-bit read from uninitialized memory in __alloc_skb
From: Eric Dumazet @ 2011-05-10 11:52 UTC (permalink / raw)
To: Pekka Enberg
Cc: Christoph Lameter, casteyde.christian, Andrew Morton, netdev,
bugzilla-daemon, bugme-daemon, Vegard Nossum
In-Reply-To: <4DC91137.4030109@cs.helsinki.fi>
Le mardi 10 mai 2011 à 13:19 +0300, Pekka Enberg a écrit :
> On 5/10/11 1:17 PM, Eric Dumazet wrote:
> > Le mardi 10 mai 2011 à 13:03 +0300, Pekka Enberg a écrit :
> >
> >> Can't we fix the issue by putting kmemcheck_mark_initialized() to
> >> set_freepointer()?
> >
> > This would solve kmemcheck problem, not DEBUG_PAGEALLOC
>
> Oh, right. Christoph? We need to support DEBUG_PAGEALLOC with SLUB.
Maybe have a special version of "irqsafe_cpu_cmpxchg_double" and make it
use something like :
local_irq_save(flags);
if (probe_kernel_address(...)) {
res = false;
} else {
res = unsafe_cpu_cmpxchg_double(...)
}
local_irq_restore(flags);
Just the idea, I dont have time to cook a patch.
^ permalink raw reply
* [patch 6/9] [PATCH] ctcm: get rid of compile warning
From: frank.blaschka @ 2011-05-10 11:50 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-s390, Ursula Braun
In-Reply-To: <20110510115013.363974020@de.ibm.com>
[-- Attachment #1: 605-ctcm-compile-warning.diff --]
[-- Type: text/plain, Size: 2987 bytes --]
From: Ursula Braun <ursula.braun@de.ibm.com>
-Wunused-but-set-variable generates compile warnings. The affected
variables are removed.
Signed-off-by: Ursula Braun <ursula.braun@de.ibm.com>
Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com>
---
drivers/s390/net/ctcm_main.c | 2 --
drivers/s390/net/ctcm_mpc.c | 13 ++++---------
2 files changed, 4 insertions(+), 11 deletions(-)
diff -urpN linux-2.6/drivers/s390/net/ctcm_main.c linux-2.6-patched/drivers/s390/net/ctcm_main.c
--- linux-2.6/drivers/s390/net/ctcm_main.c 2011-05-10 09:14:06.000000000 +0200
+++ linux-2.6-patched/drivers/s390/net/ctcm_main.c 2011-05-10 09:14:26.000000000 +0200
@@ -672,7 +672,6 @@ static int ctcmpc_transmit_skb(struct ch
int ccw_idx;
unsigned long hi;
unsigned long saveflags = 0; /* avoids compiler warning */
- __u16 block_len;
CTCM_PR_DEBUG("Enter %s: %s, cp=%i ch=0x%p id=%s state=%s\n",
__func__, dev->name, smp_processor_id(), ch,
@@ -719,7 +718,6 @@ static int ctcmpc_transmit_skb(struct ch
*/
atomic_inc(&skb->users);
- block_len = skb->len + TH_HEADER_LENGTH + PDU_HEADER_LENGTH;
/*
* IDAL support in CTCM is broken, so we have to
* care about skb's above 2G ourselves.
diff -urpN linux-2.6/drivers/s390/net/ctcm_mpc.c linux-2.6-patched/drivers/s390/net/ctcm_mpc.c
--- linux-2.6/drivers/s390/net/ctcm_mpc.c 2011-03-15 02:20:32.000000000 +0100
+++ linux-2.6-patched/drivers/s390/net/ctcm_mpc.c 2011-05-10 09:14:26.000000000 +0200
@@ -653,7 +653,6 @@ static void ctcmpc_send_sweep_resp(struc
struct net_device *dev = rch->netdev;
struct ctcm_priv *priv = dev->ml_priv;
struct mpc_group *grp = priv->mpcg;
- int rc = 0;
struct th_sweep *header;
struct sk_buff *sweep_skb;
struct channel *ch = priv->channel[CTCM_WRITE];
@@ -665,16 +664,14 @@ static void ctcmpc_send_sweep_resp(struc
CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
"%s(%s): sweep_skb allocation ERROR\n",
CTCM_FUNTAIL, rch->id);
- rc = -ENOMEM;
- goto done;
+ goto done;
}
header = kmalloc(sizeof(struct th_sweep), gfp_type());
if (!header) {
dev_kfree_skb_any(sweep_skb);
- rc = -ENOMEM;
- goto done;
+ goto done;
}
header->th.th_seg = 0x00 ;
@@ -1370,8 +1367,7 @@ static void mpc_action_go_inop(fsm_insta
struct net_device *dev = arg;
struct ctcm_priv *priv;
struct mpc_group *grp;
- int rc = 0;
- struct channel *wch, *rch;
+ struct channel *wch;
BUG_ON(dev == NULL);
CTCM_PR_DEBUG("Enter %s: %s\n", __func__, dev->name);
@@ -1396,7 +1392,6 @@ static void mpc_action_go_inop(fsm_insta
fsm_deltimer(&priv->restart_timer);
wch = priv->channel[CTCM_WRITE];
- rch = priv->channel[CTCM_READ];
switch (grp->saved_state) {
case MPCG_STATE_RESET:
@@ -1435,7 +1430,7 @@ static void mpc_action_go_inop(fsm_insta
if (grp->send_qllc_disc == 1) {
grp->send_qllc_disc = 0;
- rc = mpc_send_qllc_discontact(dev);
+ mpc_send_qllc_discontact(dev);
}
/* DO NOT issue DEV_EVENT_STOP directly out of this code */
^ permalink raw reply
* [patch 7/9] [PATCH] iucv: get rid of compile warning
From: frank.blaschka @ 2011-05-10 11:50 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-s390, Ursula Braun
In-Reply-To: <20110510115013.363974020@de.ibm.com>
[-- Attachment #1: 606-iucv-compile-warning.diff --]
[-- Type: text/plain, Size: 990 bytes --]
From: Ursula Braun <ursula.braun@de.ibm.com>
-Wunused-but-set-variable generates a compile warning. The affected
variable is removed.
Signed-off-by: Ursula Braun <ursula.braun@de.ibm.com>
Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com>
---
net/iucv/iucv.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff -urpN linux-2.6/net/iucv/iucv.c linux-2.6-patched/net/iucv/iucv.c
--- linux-2.6/net/iucv/iucv.c 2011-05-10 09:14:08.000000000 +0200
+++ linux-2.6-patched/net/iucv/iucv.c 2011-05-10 09:14:26.000000000 +0200
@@ -828,14 +828,14 @@ EXPORT_SYMBOL(iucv_unregister);
static int iucv_reboot_event(struct notifier_block *this,
unsigned long event, void *ptr)
{
- int i, rc;
+ int i;
get_online_cpus();
on_each_cpu(iucv_block_cpu, NULL, 1);
preempt_disable();
for (i = 0; i < iucv_max_pathid; i++) {
if (iucv_path_table[i])
- rc = iucv_sever_pathid(i, NULL);
+ iucv_sever_pathid(i, NULL);
}
preempt_enable();
put_online_cpus();
^ permalink raw reply
* [patch 4/9] [PATCH] claw: remove unused return code handling
From: frank.blaschka @ 2011-05-10 11:50 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-s390, Heiko Carstens
In-Reply-To: <20110510115013.363974020@de.ibm.com>
[-- Attachment #1: 603-claw-unused-rc.diff --]
[-- Type: text/plain, Size: 3801 bytes --]
From: Heiko Carstens <heiko.carstens@de.ibm.com>
Remove unused return code handling. The claw driver is mostly dead, so
just make sure it keeps compiling without warnings.
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com>
---
drivers/s390/net/claw.c | 22 +++-------------------
1 file changed, 3 insertions(+), 19 deletions(-)
diff -urpN linux-2.6/drivers/s390/net/claw.c linux-2.6-patched/drivers/s390/net/claw.c
--- linux-2.6/drivers/s390/net/claw.c 2011-05-10 09:14:06.000000000 +0200
+++ linux-2.6-patched/drivers/s390/net/claw.c 2011-05-10 09:14:25.000000000 +0200
@@ -845,12 +845,10 @@ claw_irq_tasklet ( unsigned long data )
{
struct chbk * p_ch;
struct net_device *dev;
- struct claw_privbk * privptr;
p_ch = (struct chbk *) data;
dev = (struct net_device *)p_ch->ndev;
CLAW_DBF_TEXT(4, trace, "IRQtask");
- privptr = (struct claw_privbk *)dev->ml_priv;
unpack_read(dev);
clear_bit(CLAW_BH_ACTIVE, (void *)&p_ch->flag_a);
CLAW_DBF_TEXT(4, trace, "TskletXt");
@@ -1026,7 +1024,6 @@ claw_write_next ( struct chbk * p_ch )
struct net_device *dev;
struct claw_privbk *privptr=NULL;
struct sk_buff *pk_skb;
- int rc;
CLAW_DBF_TEXT(4, trace, "claw_wrt");
if (p_ch->claw_state == CLAW_STOP)
@@ -1038,7 +1035,7 @@ claw_write_next ( struct chbk * p_ch )
!skb_queue_empty(&p_ch->collect_queue)) {
pk_skb = claw_pack_skb(privptr);
while (pk_skb != NULL) {
- rc = claw_hw_tx( pk_skb, dev,1);
+ claw_hw_tx(pk_skb, dev, 1);
if (privptr->write_free_count > 0) {
pk_skb = claw_pack_skb(privptr);
} else
@@ -1322,15 +1319,12 @@ claw_hw_tx(struct sk_buff *skb, struct n
unsigned char *pDataAddress;
struct endccw *pEnd;
struct ccw1 tempCCW;
- struct chbk *p_ch;
struct claw_env *p_env;
- int lock;
struct clawph *pk_head;
struct chbk *ch;
CLAW_DBF_TEXT(4, trace, "hw_tx");
privptr = (struct claw_privbk *)(dev->ml_priv);
- p_ch = (struct chbk *)&privptr->channel[WRITE_CHANNEL];
p_env =privptr->p_env;
claw_free_wrt_buf(dev); /* Clean up free chain if posible */
/* scan the write queue to free any completed write packets */
@@ -1511,12 +1505,6 @@ claw_hw_tx(struct sk_buff *skb, struct n
} /* endif (p_first_ccw!=NULL) */
dev_kfree_skb_any(skb);
- if (linkid==0) {
- lock=LOCK_NO;
- }
- else {
- lock=LOCK_YES;
- }
claw_strt_out_IO(dev );
/* if write free count is zero , set NOBUFFER */
if (privptr->write_free_count==0) {
@@ -2821,15 +2809,11 @@ claw_free_wrt_buf( struct net_device *de
{
struct claw_privbk *privptr = (struct claw_privbk *)dev->ml_priv;
- struct ccwbk*p_first_ccw;
- struct ccwbk*p_last_ccw;
struct ccwbk*p_this_ccw;
struct ccwbk*p_next_ccw;
CLAW_DBF_TEXT(4, trace, "freewrtb");
/* scan the write queue to free any completed write packets */
- p_first_ccw=NULL;
- p_last_ccw=NULL;
p_this_ccw=privptr->p_write_active_first;
while ( (p_this_ccw!=NULL) && (p_this_ccw->header.flag!=CLAW_PENDING))
{
@@ -3072,7 +3056,7 @@ claw_shutdown_device(struct ccwgroup_dev
{
struct claw_privbk *priv;
struct net_device *ndev;
- int ret;
+ int ret = 0;
CLAW_DBF_TEXT_(2, setup, "%s", dev_name(&cgdev->dev));
priv = dev_get_drvdata(&cgdev->dev);
@@ -3095,7 +3079,7 @@ claw_shutdown_device(struct ccwgroup_dev
}
ccw_device_set_offline(cgdev->cdev[1]);
ccw_device_set_offline(cgdev->cdev[0]);
- return 0;
+ return ret;
}
static void
^ permalink raw reply
* [patch 5/9] [PATCH] lcs: get rid of compile warning
From: frank.blaschka @ 2011-05-10 11:50 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-s390, Heiko Carstens
In-Reply-To: <20110510115013.363974020@de.ibm.com>
[-- Attachment #1: 604-lcs-compile-warning.diff --]
[-- Type: text/plain, Size: 1658 bytes --]
From: Heiko Carstens <heiko.carstens@de.ibm.com>
-Wunused-but-set-variable generates a compile warning for lcs' tasklet
function. Invoked functions contain already error handling; thus
additional return code checking is not needed here.
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com>
---
drivers/s390/net/lcs.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff -urpN linux-2.6/drivers/s390/net/lcs.c linux-2.6-patched/drivers/s390/net/lcs.c
--- linux-2.6/drivers/s390/net/lcs.c 2011-05-10 09:14:06.000000000 +0200
+++ linux-2.6-patched/drivers/s390/net/lcs.c 2011-05-10 09:14:25.000000000 +0200
@@ -1483,7 +1483,6 @@ lcs_tasklet(unsigned long data)
struct lcs_channel *channel;
struct lcs_buffer *iob;
int buf_idx;
- int rc;
channel = (struct lcs_channel *) data;
LCS_DBF_TEXT_(5, trace, "tlet%s", dev_name(&channel->ccwdev->dev));
@@ -1500,14 +1499,11 @@ lcs_tasklet(unsigned long data)
channel->buf_idx = buf_idx;
if (channel->state == LCS_CH_STATE_STOPPED)
- // FIXME: what if rc != 0 ??
- rc = lcs_start_channel(channel);
+ lcs_start_channel(channel);
spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
if (channel->state == LCS_CH_STATE_SUSPENDED &&
- channel->iob[channel->io_idx].state == LCS_BUF_STATE_READY) {
- // FIXME: what if rc != 0 ??
- rc = __lcs_resume_channel(channel);
- }
+ channel->iob[channel->io_idx].state == LCS_BUF_STATE_READY)
+ __lcs_resume_channel(channel);
spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
/* Something happened on the channel. Wake up waiters. */
^ permalink raw reply
* [patch 9/9] [PATCH] convert old cpumask API into new one
From: frank.blaschka @ 2011-05-10 11:50 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-s390, KOSAKI Motohiro
In-Reply-To: <20110510115013.363974020@de.ibm.com>
[-- Attachment #1: 608-cpumask-api.diff --]
[-- Type: text/plain, Size: 8375 bytes --]
From: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Adapt new API.
Signed-off-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com>
---
net/iucv/iucv.c | 73 ++++++++++++++++++++++++++++----------------------------
1 file changed, 37 insertions(+), 36 deletions(-)
diff -urpN linux-2.6/net/iucv/iucv.c linux-2.6-patched/net/iucv/iucv.c
--- linux-2.6/net/iucv/iucv.c 2011-05-10 09:14:27.000000000 +0200
+++ linux-2.6-patched/net/iucv/iucv.c 2011-05-10 09:14:27.000000000 +0200
@@ -128,8 +128,8 @@ struct iucv_irq_list {
};
static struct iucv_irq_data *iucv_irq_data[NR_CPUS];
-static cpumask_t iucv_buffer_cpumask = CPU_MASK_NONE;
-static cpumask_t iucv_irq_cpumask = CPU_MASK_NONE;
+static cpumask_t iucv_buffer_cpumask = { CPU_BITS_NONE };
+static cpumask_t iucv_irq_cpumask = { CPU_BITS_NONE };
/*
* Queue of interrupt buffers lock for delivery via the tasklet
@@ -406,7 +406,7 @@ static void iucv_allow_cpu(void *data)
parm->set_mask.ipmask = 0xf8;
iucv_call_b2f0(IUCV_SETCONTROLMASK, parm);
/* Set indication that iucv interrupts are allowed for this cpu. */
- cpu_set(cpu, iucv_irq_cpumask);
+ cpumask_set_cpu(cpu, &iucv_irq_cpumask);
}
/**
@@ -426,7 +426,7 @@ static void iucv_block_cpu(void *data)
iucv_call_b2f0(IUCV_SETMASK, parm);
/* Clear indication that iucv interrupts are allowed for this cpu. */
- cpu_clear(cpu, iucv_irq_cpumask);
+ cpumask_clear_cpu(cpu, &iucv_irq_cpumask);
}
/**
@@ -451,7 +451,7 @@ static void iucv_block_cpu_almost(void *
iucv_call_b2f0(IUCV_SETCONTROLMASK, parm);
/* Clear indication that iucv interrupts are allowed for this cpu. */
- cpu_clear(cpu, iucv_irq_cpumask);
+ cpumask_clear_cpu(cpu, &iucv_irq_cpumask);
}
/**
@@ -466,7 +466,7 @@ static void iucv_declare_cpu(void *data)
union iucv_param *parm;
int rc;
- if (cpu_isset(cpu, iucv_buffer_cpumask))
+ if (cpumask_test_cpu(cpu, &iucv_buffer_cpumask))
return;
/* Declare interrupt buffer. */
@@ -499,9 +499,9 @@ static void iucv_declare_cpu(void *data)
}
/* Set indication that an iucv buffer exists for this cpu. */
- cpu_set(cpu, iucv_buffer_cpumask);
+ cpumask_set_cpu(cpu, &iucv_buffer_cpumask);
- if (iucv_nonsmp_handler == 0 || cpus_empty(iucv_irq_cpumask))
+ if (iucv_nonsmp_handler == 0 || cpumask_empty(&iucv_irq_cpumask))
/* Enable iucv interrupts on this cpu. */
iucv_allow_cpu(NULL);
else
@@ -520,7 +520,7 @@ static void iucv_retrieve_cpu(void *data
int cpu = smp_processor_id();
union iucv_param *parm;
- if (!cpu_isset(cpu, iucv_buffer_cpumask))
+ if (!cpumask_test_cpu(cpu, &iucv_buffer_cpumask))
return;
/* Block iucv interrupts. */
@@ -531,7 +531,7 @@ static void iucv_retrieve_cpu(void *data
iucv_call_b2f0(IUCV_RETRIEVE_BUFFER, parm);
/* Clear indication that an iucv buffer exists for this cpu. */
- cpu_clear(cpu, iucv_buffer_cpumask);
+ cpumask_clear_cpu(cpu, &iucv_buffer_cpumask);
}
/**
@@ -546,8 +546,8 @@ static void iucv_setmask_mp(void)
get_online_cpus();
for_each_online_cpu(cpu)
/* Enable all cpus with a declared buffer. */
- if (cpu_isset(cpu, iucv_buffer_cpumask) &&
- !cpu_isset(cpu, iucv_irq_cpumask))
+ if (cpumask_test_cpu(cpu, &iucv_buffer_cpumask) &&
+ !cpumask_test_cpu(cpu, &iucv_irq_cpumask))
smp_call_function_single(cpu, iucv_allow_cpu,
NULL, 1);
put_online_cpus();
@@ -564,9 +564,9 @@ static void iucv_setmask_up(void)
int cpu;
/* Disable all cpu but the first in cpu_irq_cpumask. */
- cpumask = iucv_irq_cpumask;
- cpu_clear(first_cpu(iucv_irq_cpumask), cpumask);
- for_each_cpu_mask_nr(cpu, cpumask)
+ cpumask_copy(&cpumask, &iucv_irq_cpumask);
+ cpumask_clear_cpu(cpumask_first(&iucv_irq_cpumask), &cpumask);
+ for_each_cpu(cpu, &cpumask)
smp_call_function_single(cpu, iucv_block_cpu, NULL, 1);
}
@@ -593,7 +593,7 @@ static int iucv_enable(void)
rc = -EIO;
for_each_online_cpu(cpu)
smp_call_function_single(cpu, iucv_declare_cpu, NULL, 1);
- if (cpus_empty(iucv_buffer_cpumask))
+ if (cpumask_empty(&iucv_buffer_cpumask))
/* No cpu could declare an iucv buffer. */
goto out;
put_online_cpus();
@@ -675,15 +675,16 @@ static int __cpuinit iucv_cpu_notify(str
case CPU_DOWN_PREPARE_FROZEN:
if (!iucv_path_table)
break;
- cpumask = iucv_buffer_cpumask;
- cpu_clear(cpu, cpumask);
- if (cpus_empty(cpumask))
+ cpumask_copy(&cpumask, &iucv_buffer_cpumask);
+ cpumask_clear_cpu(cpu, &cpumask);
+ if (cpumask_empty(&cpumask))
/* Can't offline last IUCV enabled cpu. */
return notifier_from_errno(-EINVAL);
smp_call_function_single(cpu, iucv_retrieve_cpu, NULL, 1);
- if (cpus_empty(iucv_irq_cpumask))
- smp_call_function_single(first_cpu(iucv_buffer_cpumask),
- iucv_allow_cpu, NULL, 1);
+ if (cpumask_empty(&iucv_irq_cpumask))
+ smp_call_function_single(
+ cpumask_first(&iucv_buffer_cpumask),
+ iucv_allow_cpu, NULL, 1);
break;
}
return NOTIFY_OK;
@@ -866,7 +867,7 @@ int iucv_path_accept(struct iucv_path *p
int rc;
local_bh_disable();
- if (cpus_empty(iucv_buffer_cpumask)) {
+ if (cpumask_empty(&iucv_buffer_cpumask)) {
rc = -EIO;
goto out;
}
@@ -915,7 +916,7 @@ int iucv_path_connect(struct iucv_path *
spin_lock_bh(&iucv_table_lock);
iucv_cleanup_queue();
- if (cpus_empty(iucv_buffer_cpumask)) {
+ if (cpumask_empty(&iucv_buffer_cpumask)) {
rc = -EIO;
goto out;
}
@@ -975,7 +976,7 @@ int iucv_path_quiesce(struct iucv_path *
int rc;
local_bh_disable();
- if (cpus_empty(iucv_buffer_cpumask)) {
+ if (cpumask_empty(&iucv_buffer_cpumask)) {
rc = -EIO;
goto out;
}
@@ -1007,7 +1008,7 @@ int iucv_path_resume(struct iucv_path *p
int rc;
local_bh_disable();
- if (cpus_empty(iucv_buffer_cpumask)) {
+ if (cpumask_empty(&iucv_buffer_cpumask)) {
rc = -EIO;
goto out;
}
@@ -1036,7 +1037,7 @@ int iucv_path_sever(struct iucv_path *pa
int rc;
preempt_disable();
- if (cpus_empty(iucv_buffer_cpumask)) {
+ if (cpumask_empty(&iucv_buffer_cpumask)) {
rc = -EIO;
goto out;
}
@@ -1070,7 +1071,7 @@ int iucv_message_purge(struct iucv_path
int rc;
local_bh_disable();
- if (cpus_empty(iucv_buffer_cpumask)) {
+ if (cpumask_empty(&iucv_buffer_cpumask)) {
rc = -EIO;
goto out;
}
@@ -1162,7 +1163,7 @@ int __iucv_message_receive(struct iucv_p
if (msg->flags & IUCV_IPRMDATA)
return iucv_message_receive_iprmdata(path, msg, flags,
buffer, size, residual);
- if (cpus_empty(iucv_buffer_cpumask)) {
+ if (cpumask_empty(&iucv_buffer_cpumask)) {
rc = -EIO;
goto out;
}
@@ -1235,7 +1236,7 @@ int iucv_message_reject(struct iucv_path
int rc;
local_bh_disable();
- if (cpus_empty(iucv_buffer_cpumask)) {
+ if (cpumask_empty(&iucv_buffer_cpumask)) {
rc = -EIO;
goto out;
}
@@ -1274,7 +1275,7 @@ int iucv_message_reply(struct iucv_path
int rc;
local_bh_disable();
- if (cpus_empty(iucv_buffer_cpumask)) {
+ if (cpumask_empty(&iucv_buffer_cpumask)) {
rc = -EIO;
goto out;
}
@@ -1324,7 +1325,7 @@ int __iucv_message_send(struct iucv_path
union iucv_param *parm;
int rc;
- if (cpus_empty(iucv_buffer_cpumask)) {
+ if (cpumask_empty(&iucv_buffer_cpumask)) {
rc = -EIO;
goto out;
}
@@ -1411,7 +1412,7 @@ int iucv_message_send2way(struct iucv_pa
int rc;
local_bh_disable();
- if (cpus_empty(iucv_buffer_cpumask)) {
+ if (cpumask_empty(&iucv_buffer_cpumask)) {
rc = -EIO;
goto out;
}
@@ -1888,7 +1889,7 @@ static int iucv_pm_freeze(struct device
printk(KERN_WARNING "iucv_pm_freeze\n");
#endif
if (iucv_pm_state != IUCV_PM_FREEZING) {
- for_each_cpu_mask_nr(cpu, iucv_irq_cpumask)
+ for_each_cpu(cpu, &iucv_irq_cpumask)
smp_call_function_single(cpu, iucv_block_cpu_almost,
NULL, 1);
cancel_work_sync(&iucv_work);
@@ -1928,7 +1929,7 @@ static int iucv_pm_thaw(struct device *d
if (rc)
goto out;
}
- if (cpus_empty(iucv_irq_cpumask)) {
+ if (cpumask_empty(&iucv_irq_cpumask)) {
if (iucv_nonsmp_handler)
/* enable interrupts on one cpu */
iucv_allow_cpu(NULL);
@@ -1961,7 +1962,7 @@ static int iucv_pm_restore(struct device
pr_warning("Suspending Linux did not completely close all IUCV "
"connections\n");
iucv_pm_state = IUCV_PM_RESTORING;
- if (cpus_empty(iucv_irq_cpumask)) {
+ if (cpumask_empty(&iucv_irq_cpumask)) {
rc = iucv_query_maxconn();
rc = iucv_enable();
if (rc)
^ 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