* [PATCH v5 4/7] ARM: davinci: net: davinci_emac: add OF support
From: Heiko Schocher @ 2012-05-30 10:19 UTC (permalink / raw)
To: davinci-linux-open-source
Cc: Heiko Schocher, linux-arm-kernel, devicetree-discuss, netdev,
Grant Likely, Sekhar Nori, Wolfgang Denk, Anatoly Sivov
In-Reply-To: <1338373143-7467-1-git-send-email-hs@denx.de>
add of support for the davinci_emac driver.
Signed-off-by: Heiko Schocher <hs@denx.de>
Cc: davinci-linux-open-source@linux.davincidsp.com
Cc: linux-arm-kernel@lists.infradead.org
Cc: devicetree-discuss@lists.ozlabs.org
Cc: netdev@vger.kernel.org
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Sekhar Nori <nsekhar@ti.com>
Cc: Wolfgang Denk <wd@denx.de>
Cc: Anatoly Sivov <mm05@mail.ru>
---
- changes for v2:
- add comment from Anatoly Sivov
- fix typo in davinci_emac.txt
- add comment from Grant Likely:
- add prefix "ti,davinci-" to davinci specific property names
- remove version property
- use compatible name "ti,davinci-dm6460-emac"
- use devm_kzalloc()
- use of_match_ptr()
- document all new properties
- remove of_address_to_resource() and do not overwrite
resource table
- whitespace fixes
- remove hw_ram_addr as it is not used in current
board code
- no changes for v3
- changes for v4:
add comments from Nori Sekhar:
- move devictree documentation to:
Documentation/devicetree/bindings/net/davinci_emac.txt
- fix typo in it
- rename compatible property to "ti,davinci-dm6467-emac"
- remove pinmux-handle
- set version directly in pdata->version
- no changes for v5
.../devicetree/bindings/net/davinci_emac.txt | 41 +++++++++
drivers/net/ethernet/ti/davinci_emac.c | 87 +++++++++++++++++++-
2 files changed, 127 insertions(+), 1 deletions(-)
create mode 100644 Documentation/devicetree/bindings/net/davinci_emac.txt
diff --git a/Documentation/devicetree/bindings/net/davinci_emac.txt b/Documentation/devicetree/bindings/net/davinci_emac.txt
new file mode 100644
index 0000000..48b259e
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/davinci_emac.txt
@@ -0,0 +1,41 @@
+* Texas Instruments Davinci EMAC
+
+This file provides information, what the device node
+for the davinci_emac interface contains.
+
+Required properties:
+- compatible: "ti,davinci-dm6467-emac";
+- reg: Offset and length of the register set for the device
+- ti,davinci-ctrl-reg-offset: offset to control register
+- ti,davinci-ctrl-mod-reg-offset: offset to control module register
+- ti,davinci-ctrl-ram-offset: offset to control module ram
+- ti,davinci-ctrl-ram-size: size of control module ram
+- ti,davinci-rmii-en: use RMII
+- ti,davinci-no-bd-ram: has the emac controller BD RAM
+- phy-handle: Contains a phandle to an Ethernet PHY.
+ if not, davinci_emac driver defaults to 100/FULL
+- interrupts: interrupt mapping for the davinci emac interrupts sources:
+ 4 sources: <Receive Threshold Interrupt
+ Receive Interrupt
+ Transmit Interrupt
+ Miscellaneous Interrupt>
+
+Optional properties:
+- local-mac-address : 6 bytes, mac address
+
+Example (enbw_cmc board):
+ eth0: emac@1e20000 {
+ compatible = "ti,davinci-dm6467-emac";
+ reg = <0x220000 0x4000>;
+ ti,davinci-ctrl-reg-offset = <0x3000>;
+ ti,davinci-ctrl-mod-reg-offset = <0x2000>;
+ ti,davinci-ctrl-ram-offset = <0>;
+ ti,davinci-ctrl-ram-size = <0x2000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <33
+ 34
+ 35
+ 36
+ >;
+ interrupt-parent = <&intc>;
+ };
diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c
index 4da93a5..645618d 100644
--- a/drivers/net/ethernet/ti/davinci_emac.c
+++ b/drivers/net/ethernet/ti/davinci_emac.c
@@ -58,6 +58,12 @@
#include <linux/io.h>
#include <linux/uaccess.h>
#include <linux/davinci_emac.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_net.h>
+
+#include <mach/mux.h>
#include <asm/irq.h>
#include <asm/page.h>
@@ -339,6 +345,9 @@ struct emac_priv {
u32 rx_addr_type;
atomic_t cur_tx;
const char *phy_id;
+#ifdef CONFIG_OF
+ struct device_node *phy_node;
+#endif
struct phy_device *phydev;
spinlock_t lock;
/*platform specific members*/
@@ -1762,6 +1771,75 @@ static const struct net_device_ops emac_netdev_ops = {
#endif
};
+#ifdef CONFIG_OF
+static struct emac_platform_data
+ *davinci_emac_of_get_pdata(struct platform_device *pdev,
+ struct emac_priv *priv)
+{
+ struct device_node *np;
+ struct emac_platform_data *pdata = NULL;
+ const u8 *mac_addr;
+ u32 data;
+ int ret;
+
+ pdata = pdev->dev.platform_data;
+ if (!pdata) {
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ goto nodata;
+ }
+
+ np = pdev->dev.of_node;
+ if (!np)
+ goto nodata;
+ else
+ pdata->version = EMAC_VERSION_2;
+
+ mac_addr = of_get_mac_address(np);
+ if (mac_addr)
+ memcpy(pdata->mac_addr, mac_addr, ETH_ALEN);
+
+ ret = of_property_read_u32(np, "ti,davinci-ctrl-reg-offset", &data);
+ if (!ret)
+ pdata->ctrl_reg_offset = data;
+
+ ret = of_property_read_u32(np, "ti,davinci-ctrl-mod-reg-offset",
+ &data);
+ if (!ret)
+ pdata->ctrl_mod_reg_offset = data;
+
+ ret = of_property_read_u32(np, "ti,davinci-ctrl-ram-offset", &data);
+ if (!ret)
+ pdata->ctrl_ram_offset = data;
+
+ ret = of_property_read_u32(np, "ti,davinci-ctrl-ram-size", &data);
+ if (!ret)
+ pdata->ctrl_ram_size = data;
+
+ ret = of_property_read_u32(np, "ti,davinci-rmii-en", &data);
+ if (!ret)
+ pdata->rmii_en = data;
+
+ ret = of_property_read_u32(np, "ti,davinci-no-bd-ram", &data);
+ if (!ret)
+ pdata->no_bd_ram = data;
+
+ priv->phy_node = of_parse_phandle(np, "phy-handle", 0);
+ if (!priv->phy_node)
+ pdata->phy_id = "";
+
+ pdev->dev.platform_data = pdata;
+nodata:
+ return pdata;
+}
+#else
+static struct emac_platform_data
+ *davinci_emac_of_get_pdata(struct platform_device *pdev,
+ struct emac_priv *priv)
+{
+ return pdev->dev.platform_data;
+}
+#endif
/**
* davinci_emac_probe: EMAC device probe
* @pdev: The DaVinci EMAC device that we are removing
@@ -1804,7 +1882,7 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev)
spin_lock_init(&priv->lock);
- pdata = pdev->dev.platform_data;
+ pdata = davinci_emac_of_get_pdata(pdev, priv);
if (!pdata) {
dev_err(&pdev->dev, "no platform data\n");
rc = -ENODEV;
@@ -2015,6 +2093,12 @@ static const struct dev_pm_ops davinci_emac_pm_ops = {
.resume = davinci_emac_resume,
};
+static const struct of_device_id davinci_emac_of_match[] = {
+ {.compatible = "ti,davinci-dm6467-emac", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, davinci_emac_of_match);
+
/**
* davinci_emac_driver: EMAC platform driver structure
*/
@@ -2023,6 +2107,7 @@ static struct platform_driver davinci_emac_driver = {
.name = "davinci_emac",
.owner = THIS_MODULE,
.pm = &davinci_emac_pm_ops,
+ .of_match_table = of_match_ptr(davinci_emac_of_match),
},
.probe = davinci_emac_probe,
.remove = __devexit_p(davinci_emac_remove),
--
1.7.7.6
^ permalink raw reply related
* RE: Difficulties to get 1Gbps on be2net ethernet card
From: Eric Dumazet @ 2012-05-30 10:30 UTC (permalink / raw)
To: Sathya.Perla; +Cc: jhautbois, netdev
In-Reply-To: <3367B80B08154D42A3B2BC708B5D41F647C678B73F@EXMAIL.ad.emulex.com>
On Wed, 2012-05-30 at 03:04 -0700, Sathya.Perla@Emulex.Com wrote:
> >-----Original Message-----
> >From: netdev-owner@vger.kernel.org [mailto:netdev-owner@vger.kernel.org] On
> >Behalf Of Jean-Michel Hautbois
> >
> >2012/5/30 Jean-Michel Hautbois <jhautbois@gmail.com>:
> >
> >I used vmstat in order to see the differences between the two kernels.
> >The main difference is the number of interrupts per second.
> >I have an average of 87500 on 3.2 and 7500 on 2.6, 10 times lower !
> >I suspect the be2net driver to be the main cause, and I checkes the
> >/proc/interrupts file in order to be sure.
> >
> >I have for eth1-tx on 2.6.26 about 2200 interrupts per second and 23000 on 3.2.
> >BTW, it is named eth1-q0 on 3.2 (and tx and rx are the same IRQ)
> >whereas there is eth1-rx0 and eth1-tx on 2.6.26.
>
> Yes, there is an issue with be2net interrupt mitigation in the recent code with
> RX and TX on the same Evt-Q (commit 10ef9ab4). The high interrupt rate happens when a TX blast is
> done while RX is relatively silent on a queue pair. Interrupt rate due to TX completions is not being
> mitigated.
>
> I have a fix and will send it out soon..
I also have a benet fix for non GRO :
Pulling 64 bytes in skb head is too much for TCP IPv4 with no
timestamps, as this makes splice() or TCP coalescing less effective.
(Having tcp payload in linear part of the skb disables various optims)
Could you please test it ?
Thanks
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 08efd30..f446b11 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -1202,15 +1202,19 @@ static void skb_fill_rx_data(struct be_rx_obj *rxo, struct sk_buff *skb,
/* Copy data in the first descriptor of this completion */
curr_frag_len = min(rxcp->pkt_size, rx_frag_size);
- /* Copy the header portion into skb_data */
- hdr_len = min(BE_HDR_LEN, curr_frag_len);
+ /* If frame is small enough to fit in skb->head, pull it completely.
+ * If not, only pull ethernet header so that splice() or TCP coalesce
+ * are more efficient.
+ */
+ hdr_len = (curr_frag_len <= skb_tailroom(skb)) ?
+ curr_frag_len : ETH_HLEN;
+
memcpy(skb->data, start, hdr_len);
skb->len = curr_frag_len;
- if (curr_frag_len <= BE_HDR_LEN) { /* tiny packet */
+ skb->tail += hdr_len;
+ if (hdr_len == curr_frag_len) { /* tiny packet */
/* Complete packet has now been moved to data */
put_page(page_info->page);
- skb->data_len = 0;
- skb->tail += curr_frag_len;
} else {
skb_shinfo(skb)->nr_frags = 1;
skb_frag_set_page(skb, 0, page_info->page);
@@ -1219,7 +1223,6 @@ static void skb_fill_rx_data(struct be_rx_obj *rxo, struct sk_buff *skb,
skb_frag_size_set(&skb_shinfo(skb)->frags[0], curr_frag_len - hdr_len);
skb->data_len = curr_frag_len - hdr_len;
skb->truesize += rx_frag_size;
- skb->tail += hdr_len;
}
page_info->page = NULL;
^ permalink raw reply related
* Re: Strange latency spikes/TX network stalls on Sun Fire X4150(x86) and e1000e
From: Hiroaki SHIMODA @ 2012-05-30 10:43 UTC (permalink / raw)
To: Eric Dumazet
Cc: Tom Herbert, Denys Fedoryshchenko, netdev, e1000-devel,
jeffrey.t.kirsher, jesse.brandeburg, davem
In-Reply-To: <1338367231.2760.125.camel@edumazet-glaptop>
On Wed, 30 May 2012 10:40:31 +0200
Eric Dumazet <eric.dumazet@gmail.com> wrote:
> On Wed, 2012-05-30 at 09:06 +0900, Hiroaki SHIMODA wrote:
> > While reading the bql code, I have some questions.
> >
> > 1) dql_completed() and dql_queued() can be called concurrently,
> > so dql->num_queued could change while processing
> > dql_completed().
> > Is it intentional to refer num_queued from "dql->" each time ?
> >
>
> not sure it can have problems, but doing the read once is indeed a good
> plan.
>
> > 2) From the comment in the code
> > * - The queue was over-limit in the previous interval and
> > * when enqueuing it was possible that all queued data
> > * had been consumed.
> >
> > and
> >
> > * Queue was not starved, check if the limit can be decreased.
> > * A decrease is only considered if the queue has been busy in
> > * the whole interval (the check above).
> >
> > the calculation of all_prev_completed should take into account
> > completed == dql->prev_num_queued case ?
> > On current implementation, limit shrinks easily and some NIC
> > hit TX stalls.
> > To mitigate TX stalls, should we fix all_prev_completed rather
> > than individual driver ?
> >
>
> Not sure what you mean
While examining ping problem, below pattern is often observed.
TIME
dql_queued() dql_completed() |
a) initial state |
|
b) X bytes queued V
c) Y bytes queued
d) X bytes completed
e) Z bytes queued
f) Y bytes completed
a) dql->limit has already some value and there is no in-flight packet.
b) X bytes queued.
c) Y bytes queued and excess limit.
d) X bytes completed and dql->prev_ovlimit is set and also
dql->prev_num_queued is set Y.
e) Z bytes queued.
f) Y bytes completed. inprogress and prev_inprogress are true.
At f), if I read the comment correctly, all_prev_completed becomes
true and limit should be increased. But POSDIFF() ignores
(A == B) case, so limit is decreased.
I thought excess limit decrement induces the TX stalls.
>
> > 3) limit calculation fails to consider integer wrap around in
> > one place ?
> >
>
> Yes
>
> > Here is the patch what I meant.
> >
> > diff --git a/lib/dynamic_queue_limits.c b/lib/dynamic_queue_limits.c
> > @@ -11,22 +11,27 @@
> > #include <linux/dynamic_queue_limits.h>
> >
> > #define POSDIFF(A, B) ((A) > (B) ? (A) - (B) : 0)
> > +#define POSDIFFI(A, B) ((int)((A) - (B)) > 0 ? (A) - (B) : 0)
> > +#define AFTER_EQ(A, B) ((int)((A) - (B)) >= 0)
> >
> > /* Records completed count and recalculates the queue limit */
> > void dql_completed(struct dql *dql, unsigned int count)
> > {
> > unsigned int inprogress, prev_inprogress, limit;
> > - unsigned int ovlimit, all_prev_completed, completed;
> > + unsigned int ovlimit, completed, num_queued;
> > + bool all_prev_completed;
> > +
> > + num_queued = dql->num_queued;
>
>
> I suggest :
>
> num_queued = ACCESS_ONCE(dql->num_queued);
>
> Or else compiler is free to do whatever he wants.
Thank you for your suggestion.
^ permalink raw reply
* RE: Strange latency spikes/TX network stalls on Sun Fire X4150(x86) and e1000e
From: David Laight @ 2012-05-30 10:52 UTC (permalink / raw)
To: Eric Dumazet, Hiroaki SHIMODA
Cc: Tom Herbert, Denys Fedoryshchenko, netdev, e1000-devel,
jeffrey.t.kirsher, jesse.brandeburg, davem
In-Reply-To: <1338367231.2760.125.camel@edumazet-glaptop>
> > + num_queued = dql->num_queued;
>
>
> I suggest :
>
> num_queued = ACCESS_ONCE(dql->num_queued);
>
> Or else compiler is free to do whatever he wants.
Or make the structure member volatile, then the
compiler can only read it once.
Probably worth while if the value is expected to
be read like that.
David
^ permalink raw reply
* RE: Strange latency spikes/TX network stalls on Sun Fire X4150(x86) and e1000e
From: Eric Dumazet @ 2012-05-30 11:04 UTC (permalink / raw)
To: David Laight
Cc: Hiroaki SHIMODA, Tom Herbert, Denys Fedoryshchenko, netdev,
e1000-devel, jeffrey.t.kirsher, jesse.brandeburg, davem
In-Reply-To: <AE90C24D6B3A694183C094C60CF0A2F6026B6F31@saturn3.aculab.com>
On Wed, 2012-05-30 at 11:52 +0100, David Laight wrote:
> > > + num_queued = dql->num_queued;
> >
> >
> > I suggest :
> >
> > num_queued = ACCESS_ONCE(dql->num_queued);
> >
> > Or else compiler is free to do whatever he wants.
>
> Or make the structure member volatile, then the
> compiler can only read it once.
No. Compiler can read it several times. Really.
> Probably worth while if the value is expected to
> be read like that.
Please don't use lazy volatile.
Unless you really want Linus flames (and ours)
ACCESS_ONCE() is much cleaner.
^ permalink raw reply
* Re: Strange latency spikes/TX network stalls on Sun Fire X4150(x86) and e1000e
From: Eric Dumazet @ 2012-05-30 11:08 UTC (permalink / raw)
To: Hiroaki SHIMODA
Cc: Tom Herbert, Denys Fedoryshchenko, netdev, e1000-devel,
jeffrey.t.kirsher, jesse.brandeburg, davem
In-Reply-To: <20120530194355.92bf5d51.shimoda.hiroaki@gmail.com>
On Wed, 2012-05-30 at 19:43 +0900, Hiroaki SHIMODA wrote:
> While examining ping problem, below pattern is often observed.
>
> TIME
> dql_queued() dql_completed() |
> a) initial state |
> |
> b) X bytes queued V
>
> c) Y bytes queued
> d) X bytes completed
> e) Z bytes queued
> f) Y bytes completed
>
> a) dql->limit has already some value and there is no in-flight packet.
> b) X bytes queued.
> c) Y bytes queued and excess limit.
> d) X bytes completed and dql->prev_ovlimit is set and also
> dql->prev_num_queued is set Y.
> e) Z bytes queued.
> f) Y bytes completed. inprogress and prev_inprogress are true.
>
> At f), if I read the comment correctly, all_prev_completed becomes
> true and limit should be increased. But POSDIFF() ignores
> (A == B) case, so limit is decreased.
Which POSDIFF(), because there are many ;)
By the way, given complexity of this I suggest you split your ideas in
independent patches.
Mabe we should change all POSDIFF(), not selected ones.
#define POSDIFF(A, B) ((int)((A) - (B)) > 0 ? (A) - (B) : 0)
^ permalink raw reply
* RE: Difficulties to get 1Gbps on be2net ethernet card
From: Sathya.Perla @ 2012-05-30 11:10 UTC (permalink / raw)
To: eric.dumazet; +Cc: jhautbois, netdev
In-Reply-To: <1338373857.2760.150.camel@edumazet-glaptop>
>-----Original Message-----
>From: Eric Dumazet [mailto:eric.dumazet@gmail.com]
>
>I also have a benet fix for non GRO :
>
>Pulling 64 bytes in skb head is too much for TCP IPv4 with no
>timestamps, as this makes splice() or TCP coalescing less effective.
>
>(Having tcp payload in linear part of the skb disables various optims)
>
>Could you please test it ?
>
Sure! thanks...
^ permalink raw reply
* RE: Strange latency spikes/TX network stalls on Sun Fire X4150(x86) and e1000e
From: Eric Dumazet @ 2012-05-30 11:12 UTC (permalink / raw)
To: David Laight
Cc: Hiroaki SHIMODA, Tom Herbert, Denys Fedoryshchenko, netdev,
e1000-devel, jeffrey.t.kirsher, jesse.brandeburg, davem
In-Reply-To: <1338375895.2760.153.camel@edumazet-glaptop>
On Wed, 2012-05-30 at 13:04 +0200, Eric Dumazet wrote:
> Please don't use lazy volatile.
>
> Unless you really want Linus flames (and ours)
>
> ACCESS_ONCE() is much cleaner.
>
http://yarchive.net/comp/linux/ACCESS_ONCE.html
^ permalink raw reply
* Re: Strange latency spikes/TX network stalls on Sun Fire X4150(x86) and e1000e
From: Joe Perches @ 2012-05-30 11:20 UTC (permalink / raw)
To: Eric Dumazet
Cc: Denys Fedoryshchenko, e1000-devel, netdev, jesse.brandeburg,
davem, Tom Herbert
In-Reply-To: <1338376107.2760.156.camel@edumazet-glaptop>
On Wed, 2012-05-30 at 13:08 +0200, Eric Dumazet wrote:
> Maybe we should change all POSDIFF(), not selected ones.
> #define POSDIFF(A, B) ((int)((A) - (B)) > 0 ? (A) - (B) : 0)
maybe use an eval once statement expression macro
({
typeof (A) _a = (A);
typeof (B) _b = (B);
((int)(_a - _b) > 0 ? _a - _b : 0;
})
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel® Ethernet, visit http://communities.intel.com/community/wired
^ permalink raw reply
* Re: [RFC PATCH 2/2] tcp: Early SYN limit and SYN cookie handling to mitigate SYN floods
From: Hans Schillstrom @ 2012-05-30 11:14 UTC (permalink / raw)
To: Eric Dumazet
Cc: Andi Kleen, Jesper Dangaard Brouer, Jesper Dangaard Brouer,
netdev@vger.kernel.org, Christoph Paasch, David S. Miller,
Martin Topholm, Florian Westphal, Tom Herbert
In-Reply-To: <1338366288.2760.115.camel@edumazet-glaptop>
On Wednesday 30 May 2012 10:24:48 Eric Dumazet wrote:
> On Wed, 2012-05-30 at 10:03 +0200, Hans Schillstrom wrote:
>
> > We have this option running right now, and it gave slightly higher values.
> > The upside is only one core is running at 100% load.
> >
> > To be able to process more SYN an attempt was made to spread them with RPS to
> > 2 other cores gave 60% more SYN:s per sec
> > i.e. syn filter in NIC sending all irq:s to one core gave ~ 52k syn. pkts/sec
> > adding RPS and sending syn to two other core:s gave ~80k syn. pkts/sec
> > Adding more cores than two didn't help that much.
>
> When you say 52.000 pkt/s, is that for fully established sockets, or
> SYNFLOOD ?
SYN Flood with hping3 random source ip, dest port 5060
and there is a listener on that port.
(kernel 3.0.13)
> 19.23 us to handle _one_ SYN message seems pretty wrong to me, if there
> is no contention on listener socket.
>
BTW.
I also see a strange behavior during SYN flood.
The client starts data sending directly in the ack,
and that first packet is more or less always retransmitted once.
I'll dig into that later, or do anyone have an idea of the reason ?
^ permalink raw reply
* Re: Strange latency spikes/TX network stalls on Sun Fire X4150(x86) and e1000e
From: Hiroaki SHIMODA @ 2012-05-30 11:29 UTC (permalink / raw)
To: Eric Dumazet
Cc: Denys Fedoryshchenko, e1000-devel, netdev, jesse.brandeburg,
davem, Tom Herbert
In-Reply-To: <1338376107.2760.156.camel@edumazet-glaptop>
On Wed, 30 May 2012 13:08:27 +0200
Eric Dumazet <eric.dumazet@gmail.com> wrote:
> On Wed, 2012-05-30 at 19:43 +0900, Hiroaki SHIMODA wrote:
>
> > While examining ping problem, below pattern is often observed.
> >
> > TIME
> > dql_queued() dql_completed() |
> > a) initial state |
> > |
> > b) X bytes queued V
> >
> > c) Y bytes queued
> > d) X bytes completed
> > e) Z bytes queued
> > f) Y bytes completed
> >
> > a) dql->limit has already some value and there is no in-flight packet.
> > b) X bytes queued.
> > c) Y bytes queued and excess limit.
> > d) X bytes completed and dql->prev_ovlimit is set and also
> > dql->prev_num_queued is set Y.
> > e) Z bytes queued.
> > f) Y bytes completed. inprogress and prev_inprogress are true.
> >
> > At f), if I read the comment correctly, all_prev_completed becomes
> > true and limit should be increased. But POSDIFF() ignores
> > (A == B) case, so limit is decreased.
>
> Which POSDIFF(), because there are many ;)
I mean,
all_prev_completed = POSDIFF(completed, dql->prev_num_queued);
> By the way, given complexity of this I suggest you split your ideas in
> independent patches.
In this case, here is the patch what I thinking.
diff --git a/lib/dynamic_queue_limits.c b/lib/dynamic_queue_limits.c
@@ -11,12 +11,14 @@
#include <linux/dynamic_queue_limits.h>
#define POSDIFF(A, B) ((A) > (B) ? (A) - (B) : 0)
+#define #define AFTER_EQ(A, B) ((int)((A) - (B)) >= 0)
/* Records completed count and recalculates the queue limit */
void dql_completed(struct dql *dql, unsigned int count)
{
unsigned int inprogress, prev_inprogress, limit;
- unsigned int ovlimit, all_prev_completed, completed;
+ unsigned int ovlimit, completed;
+ bool all_prev_completed;
/* Can't complete more than what's in queue */
BUG_ON(count > dql->num_queued - dql->num_completed);
@@ -26,7 +28,7 @@ void dql_completed(struct dql *dql, unsigned int count)
ovlimit = POSDIFF(dql->num_queued - dql->num_completed, limit);
inprogress = dql->num_queued - completed;
prev_inprogress = dql->prev_num_queued - dql->num_completed;
- all_prev_completed = POSDIFF(completed, dql->prev_num_queued);
+ all_prev_completed = AFTER_EQ(completed, dql->prev_num_queued);
if ((ovlimit && !inprogress) ||
(dql->prev_ovlimit && all_prev_completed)) {
> Mabe we should change all POSDIFF(), not selected ones.
>
> #define POSDIFF(A, B) ((int)((A) - (B)) > 0 ? (A) - (B) : 0)
>
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel® Ethernet, visit http://communities.intel.com/community/wired
^ permalink raw reply
* Re: Strange latency spikes/TX network stalls on Sun Fire X4150(x86) and e1000e
From: Eric Dumazet @ 2012-05-30 11:59 UTC (permalink / raw)
To: Joe Perches
Cc: Hiroaki SHIMODA, Tom Herbert, Denys Fedoryshchenko, netdev,
e1000-devel, jeffrey.t.kirsher, jesse.brandeburg, davem
In-Reply-To: <1338376817.32113.5.camel@joe2Laptop>
On Wed, 2012-05-30 at 04:20 -0700, Joe Perches wrote:
> On Wed, 2012-05-30 at 13:08 +0200, Eric Dumazet wrote:
> > Maybe we should change all POSDIFF(), not selected ones.
> > #define POSDIFF(A, B) ((int)((A) - (B)) > 0 ? (A) - (B) : 0)
>
> maybe use an eval once statement expression macro
> ({
> typeof (A) _a = (A);
> typeof (B) _b = (B);
> ((int)(_a - _b) > 0 ? _a - _b : 0;
> })
>
>
Well, many choices are possible, including
#define POSDIFF(A, B) max_t(int, (A) - (B), 0);
^ permalink raw reply
* Re: [RFC PATCH 0/4] inet: add second hash table
From: Daniel Baluta @ 2012-05-30 12:32 UTC (permalink / raw)
To: Eric Dumazet
Cc: Alexandru Copot, davem, gerrit, kuznet, jmorris, yoshfuji, kaber,
netdev, Lucian Grijincu
In-Reply-To: <1338364640.2760.96.camel@edumazet-glaptop>
On Wed, May 30, 2012 at 10:57 AM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> On Wed, 2012-05-30 at 10:36 +0300, Alexandru Copot wrote:
>> This patchset implements all the operations needed to use a second
>> (port,address) bind hash table for inet. It uses a similar approach
>> as the UDP implementation.
>>
>> The performance improvements for port allocation are very good and
>> detailed in the last message.
>>
>> This is based on a series of patches written by Lucian Grijincu at Ixia.
>>
>> Signed-off-by: Alexandru Copot <alex.mihai.c@gmail.com>
>> Cc: Daniel Baluta <dbaluta@ixiacom.com>
>> Cc: Lucian Grijincu <lucian.grijincu@gmail.com>
>> ---
>> Alexandru Copot (4):
>> inet: add counter to inet_bind_hashbucket
>> inet: add a second bind hash
>> inet: add/remove inet buckets in the second bind hash
>> inet: use second hash in inet_csk_get_port
>>
>> include/net/inet_hashtables.h | 140 +++++++++++++++++++++++++++++++--
>> include/net/inet_timewait_sock.h | 5 +-
>> net/dccp/proto.c | 37 ++++++++-
>> net/ipv4/inet_connection_sock.c | 66 ++++++++--------
>> net/ipv4/inet_hashtables.c | 158 ++++++++++++++++++++++++++++++++++++--
>> net/ipv4/inet_timewait_sock.c | 16 ++--
>> net/ipv4/tcp.c | 17 ++++
>> net/ipv6/inet6_hashtables.c | 95 +++++++++++++++++++++++
>> 8 files changed, 477 insertions(+), 57 deletions(-)
>
>
> Its a huge change (with many details to look at), for a yet to be
> understood need.
>
> What sensible workload needs this at all ?
Hi Eric,
Usually our tests use a huge number of virtual interfaces.
Using this patch we get a massive improvement when there are many sockets
bound to the same port, but different addresses for both bind() and
listen() system calls (both call inet_csk_get_port).
We provided some data points in the fourth patch:
For 16.000 interfaces each with a distinct IPv4 address, doing bind
and then listen we get:
* Without patch and without SO_REUSEADDR:
* bind: 1.543 s
* listen: 3.050 s
* Without patch and with SO_REUSEADDR set:
* bind: 0.066 s
* listen: 3.050 s
* With patch and SO_REUSEADDR set / without SO_REUSEADDR:
* bind: 0.066 s
* listen: 0.095 s
The source code for tests can be found here [1].
Just run:
* ./prepare_test2.sh
* ./avg_tcp.sh
If I understood it correctly, a similar patch was introduced
for UDP some time ago. [2]
thanks,
Daniel.
[1] http://ixlabs.cs.pub.ro/gitweb/?p=port-allocation.git;a=tree;f=testbind;h=687e4452101e13cb5995b43c1351d76786d98fdd;hb=HEAD
[2] http://www.spinics.net/lists/netdev/msg112056.html
^ permalink raw reply
* Re: [RFC PATCH 0/4] inet: add second hash table
From: Eric Dumazet @ 2012-05-30 12:41 UTC (permalink / raw)
To: Daniel Baluta
Cc: Alexandru Copot, davem, gerrit, kuznet, jmorris, yoshfuji, kaber,
netdev, Lucian Grijincu
In-Reply-To: <CAEnQRZD3o_+fRnnbd74VeFuNvjAVVyq-rE241J96iRXWFDAEPQ@mail.gmail.com>
On Wed, 2012-05-30 at 15:32 +0300, Daniel Baluta wrote:
> Hi Eric,
>
> Usually our tests use a huge number of virtual interfaces.
> Using this patch we get a massive improvement when there are many sockets
> bound to the same port, but different addresses for both bind() and
> listen() system calls (both call inet_csk_get_port).
>
> We provided some data points in the fourth patch:
>
> For 16.000 interfaces each with a distinct IPv4 address, doing bind
> and then listen we get:
>
>
> If I understood it correctly, a similar patch was introduced
> for UDP some time ago. [2]
>
> thanks,
> Daniel.
>
> [1] http://ixlabs.cs.pub.ro/gitweb/?p=port-allocation.git;a=tree;f=testbind;h=687e4452101e13cb5995b43c1351d76786d98fdd;hb=HEAD
> [2] http://www.spinics.net/lists/netdev/msg112056.html
UDP case was a bit different, since production machine could really have
thousand of UDP flows for tunnel terminations.
But for TCP, unless your very specific needs I don't see the real need
to review 400 lines of patches ?
Nobody but you ever complained of listen() being performance critical
with 16.000 IP on a machime...
^ permalink raw reply
* Re: Strange latency spikes/TX network stalls on Sun Fire X4150(x86) and e1000e
From: Joe Perches @ 2012-05-30 14:09 UTC (permalink / raw)
To: Eric Dumazet
Cc: Denys Fedoryshchenko, e1000-devel, netdev, jesse.brandeburg,
davem, Tom Herbert
In-Reply-To: <1338379151.2760.166.camel@edumazet-glaptop>
On Wed, 2012-05-30 at 13:59 +0200, Eric Dumazet wrote:
> On Wed, 2012-05-30 at 04:20 -0700, Joe Perches wrote:
> > On Wed, 2012-05-30 at 13:08 +0200, Eric Dumazet wrote:
> > > Maybe we should change all POSDIFF(), not selected ones.
> > > #define POSDIFF(A, B) ((int)((A) - (B)) > 0 ? (A) - (B) : 0)
> >
> > maybe use an eval once statement expression macro
> > ({
> > typeof (A) _a = (A);
> > typeof (B) _b = (B);
> > ((int)(_a - _b) > 0 ? _a - _b : 0;
> > })
>
> Well, many choices are possible, including
> #define POSDIFF(A, B) max_t(int, (A) - (B), 0);
Maybe. If the intent to always return an int.
The current macro doesn't.
Whatever evals A and B once would be better.
cheers, Joe
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel® Ethernet, visit http://communities.intel.com/community/wired
^ permalink raw reply
* [PATCH repost] virtio-net: remove useless disable on freeze
From: Michael S. Tsirkin @ 2012-05-30 14:21 UTC (permalink / raw)
To: Rusty Russell, Michael S. Tsirkin, virtualization, netdev,
linux-kernel
disable_cb is just an optimization: it
can not guarantee that there are no callbacks.
In particular it doesn't have any effect when
event index is on.
Instead, detach, napi disable and reset on freeze ensure we don't run
concurrently with a callback.
Remove the useless calls so we get same behaviour
with and without event index.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
Reposting a patch that seems to have fallen through cracks.
drivers/net/virtio_net.c | 5 -----
1 files changed, 0 insertions(+), 5 deletions(-)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 9ce6995..5214b1e 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1231,11 +1231,6 @@ static int virtnet_freeze(struct virtio_device *vdev)
vi->config_enable = false;
mutex_unlock(&vi->config_lock);
- virtqueue_disable_cb(vi->rvq);
- virtqueue_disable_cb(vi->svq);
- if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ))
- virtqueue_disable_cb(vi->cvq);
-
netif_device_detach(vi->dev);
cancel_delayed_work_sync(&vi->refill);
--
MST
^ permalink raw reply related
* Re: Strange latency spikes/TX network stalls on Sun Fire X4150(x86) and e1000e
From: Eric Dumazet @ 2012-05-30 14:42 UTC (permalink / raw)
To: Joe Perches
Cc: Denys Fedoryshchenko, e1000-devel, netdev, jesse.brandeburg,
davem, Tom Herbert
In-Reply-To: <1338386973.32113.23.camel@joe2Laptop>
On Wed, 2012-05-30 at 07:09 -0700, Joe Perches wrote:
> Whatever evals A and B once would be better.
Why do you believe they could be evaluated several time ?
#define POSDIFF(A, B) max_t(int, (A) - (B), 0)
(A) - (B) is done once, or its a huge max_t() bug.
By the way, we handle 32bit values here. No way BQL can overflow a 4GB
limit.
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel® Ethernet, visit http://communities.intel.com/community/wired
^ permalink raw reply
* Re: Strange latency spikes/TX network stalls on Sun Fire X4150(x86) and e1000e
From: Eric Dumazet @ 2012-05-30 14:49 UTC (permalink / raw)
To: Hiroaki SHIMODA
Cc: Denys Fedoryshchenko, e1000-devel, netdev, jesse.brandeburg,
davem, Tom Herbert
In-Reply-To: <20120530202917.b2642929.shimoda.hiroaki@gmail.com>
On Wed, 2012-05-30 at 20:29 +0900, Hiroaki SHIMODA wrote:
> On Wed, 30 May 2012 13:08:27 +0200
> Eric Dumazet <eric.dumazet@gmail.com> wrote:
>
> > On Wed, 2012-05-30 at 19:43 +0900, Hiroaki SHIMODA wrote:
> >
> > > While examining ping problem, below pattern is often observed.
> > >
> > > TIME
> > > dql_queued() dql_completed() |
> > > a) initial state |
> > > |
> > > b) X bytes queued V
> > >
> > > c) Y bytes queued
> > > d) X bytes completed
> > > e) Z bytes queued
> > > f) Y bytes completed
> > >
> > > a) dql->limit has already some value and there is no in-flight packet.
> > > b) X bytes queued.
> > > c) Y bytes queued and excess limit.
> > > d) X bytes completed and dql->prev_ovlimit is set and also
> > > dql->prev_num_queued is set Y.
> > > e) Z bytes queued.
> > > f) Y bytes completed. inprogress and prev_inprogress are true.
> > >
> > > At f), if I read the comment correctly, all_prev_completed becomes
> > > true and limit should be increased. But POSDIFF() ignores
> > > (A == B) case, so limit is decreased.
> >
> > Which POSDIFF(), because there are many ;)
>
> I mean,
> all_prev_completed = POSDIFF(completed, dql->prev_num_queued);
>
> > By the way, given complexity of this I suggest you split your ideas in
> > independent patches.
>
> In this case, here is the patch what I thinking.
>
> diff --git a/lib/dynamic_queue_limits.c b/lib/dynamic_queue_limits.c
> @@ -11,12 +11,14 @@
> #include <linux/dynamic_queue_limits.h>
>
> #define POSDIFF(A, B) ((A) > (B) ? (A) - (B) : 0)
> +#define #define AFTER_EQ(A, B) ((int)((A) - (B)) >= 0)
>
> /* Records completed count and recalculates the queue limit */
> void dql_completed(struct dql *dql, unsigned int count)
> {
> unsigned int inprogress, prev_inprogress, limit;
> - unsigned int ovlimit, all_prev_completed, completed;
> + unsigned int ovlimit, completed;
> + bool all_prev_completed;
>
> /* Can't complete more than what's in queue */
> BUG_ON(count > dql->num_queued - dql->num_completed);
> @@ -26,7 +28,7 @@ void dql_completed(struct dql *dql, unsigned int count)
> ovlimit = POSDIFF(dql->num_queued - dql->num_completed, limit);
> inprogress = dql->num_queued - completed;
> prev_inprogress = dql->prev_num_queued - dql->num_completed;
> - all_prev_completed = POSDIFF(completed, dql->prev_num_queued);
> + all_prev_completed = AFTER_EQ(completed, dql->prev_num_queued);
>
> if ((ovlimit && !inprogress) ||
> (dql->prev_ovlimit && all_prev_completed)) {
I am fine with this one.
Can you send official patches please ?
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel® Ethernet, visit http://communities.intel.com/community/wired
^ permalink raw reply
* Re: Strange latency spikes/TX network stalls on Sun Fire X4150(x86) and e1000e
From: Joe Perches @ 2012-05-30 14:50 UTC (permalink / raw)
To: Eric Dumazet
Cc: Denys Fedoryshchenko, e1000-devel, netdev, jesse.brandeburg,
davem, Tom Herbert
In-Reply-To: <1338388974.2760.193.camel@edumazet-glaptop>
On Wed, 2012-05-30 at 16:42 +0200, Eric Dumazet wrote:
> On Wed, 2012-05-30 at 07:09 -0700, Joe Perches wrote:
>
> > Whatever evals A and B once would be better.
>
> Why do you believe they could be evaluated several time ?
>
> #define POSDIFF(A, B) max_t(int, (A) - (B), 0)
I don't and didn't say I did.
> By the way, we handle 32bit values here. No way BQL can overflow a 4GB
> limit.
swell.
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel® Ethernet, visit http://communities.intel.com/community/wired
^ permalink raw reply
* Re: Strange latency spikes/TX network stalls on Sun Fire X4150(x86) and e1000e
From: dave taht @ 2012-05-30 15:00 UTC (permalink / raw)
To: Eric Dumazet
Cc: Hiroaki SHIMODA, Tom Herbert, Denys Fedoryshchenko, netdev,
e1000-devel, jeffrey.t.kirsher, jesse.brandeburg, davem
In-Reply-To: <1338389342.2760.195.camel@edumazet-glaptop>
On 05/30/2012 07:49 AM, Eric Dumazet wrote:
> On Wed, 2012-05-30 at 20:29 +0900, Hiroaki SHIMODA wrote:
>> On Wed, 30 May 2012 13:08:27 +0200
>> Eric Dumazet<eric.dumazet@gmail.com> wrote:
>>
>>> On Wed, 2012-05-30 at 19:43 +0900, Hiroaki SHIMODA wrote:
>>>
>>>> While examining ping problem, below pattern is often observed.
>>>>
>>>> TIME
>>>> dql_queued() dql_completed() |
>>>> a) initial state |
>>>> |
>>>> b) X bytes queued V
>>>>
>>>> c) Y bytes queued
>>>> d) X bytes completed
>>>> e) Z bytes queued
>>>> f) Y bytes completed
>>>>
>>>> a) dql->limit has already some value and there is no in-flight packet.
>>>> b) X bytes queued.
>>>> c) Y bytes queued and excess limit.
>>>> d) X bytes completed and dql->prev_ovlimit is set and also
>>>> dql->prev_num_queued is set Y.
>>>> e) Z bytes queued.
>>>> f) Y bytes completed. inprogress and prev_inprogress are true.
>>>>
>>>> At f), if I read the comment correctly, all_prev_completed becomes
>>>> true and limit should be increased. But POSDIFF() ignores
>>>> (A == B) case, so limit is decreased.
>>> Which POSDIFF(), because there are many ;)
>> I mean,
>> all_prev_completed = POSDIFF(completed, dql->prev_num_queued);
>>
>>> By the way, given complexity of this I suggest you split your ideas in
>>> independent patches.
>> In this case, here is the patch what I thinking.
>>
>> diff --git a/lib/dynamic_queue_limits.c b/lib/dynamic_queue_limits.c
>> @@ -11,12 +11,14 @@
>> #include<linux/dynamic_queue_limits.h>
>>
>> #define POSDIFF(A, B) ((A)> (B) ? (A) - (B) : 0)
>> +#define #define AFTER_EQ(A, B) ((int)((A) - (B))>= 0)
>>
>> /* Records completed count and recalculates the queue limit */
>> void dql_completed(struct dql *dql, unsigned int count)
>> {
>> unsigned int inprogress, prev_inprogress, limit;
>> - unsigned int ovlimit, all_prev_completed, completed;
>> + unsigned int ovlimit, completed;
>> + bool all_prev_completed;
>>
>> /* Can't complete more than what's in queue */
>> BUG_ON(count> dql->num_queued - dql->num_completed);
>> @@ -26,7 +28,7 @@ void dql_completed(struct dql *dql, unsigned int count)
>> ovlimit = POSDIFF(dql->num_queued - dql->num_completed, limit);
>> inprogress = dql->num_queued - completed;
>> prev_inprogress = dql->prev_num_queued - dql->num_completed;
>> - all_prev_completed = POSDIFF(completed, dql->prev_num_queued);
>> + all_prev_completed = AFTER_EQ(completed, dql->prev_num_queued);
>>
>> if ((ovlimit&& !inprogress) ||
>> (dql->prev_ovlimit&& all_prev_completed)) {
> I am fine with this one.
>
> Can you send official patches please ?
While this looks encouraging, BQL presently overbuffers by about a
factor of 2 in low (sub 100Mbit) scenarios
on the hardware I have available to me.
I look forward to re-running benchmarks with this patch however.
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: bug in ip -s xfrm state list
From: Stephen Hemminger @ 2012-05-30 15:13 UTC (permalink / raw)
To: Jaroslav Šafka; +Cc: netdev
In-Reply-To: <1938601.tRGYljKHkq@notebook>
On Wed, 30 May 2012 15:00:05 +0200
Jaroslav Šafka <jaroslav.safka@siemens.com> wrote:
> Hello guys,
> I found small problem in printing "seq" number.
> I think the problem is visible in diff below ;-)
>
> Best regards
> Jarek
>
> diff --git a/ip/ipxfrm.c b/ip/ipxfrm.c
> index c7b3420..67fe838 100644
> --- a/ip/ipxfrm.c
> +++ b/ip/ipxfrm.c
> @@ -843,7 +843,7 @@ void xfrm_state_info_print(struct xfrm_usersa_info
> *xsinfo,
> fputs(buf, fp);
> fprintf(fp, "replay-window %u ", xsinfo->replay_window);
> if (show_stats > 0)
> - fprintf(fp, "seq 0x%08u ", xsinfo->seq);
> + fprintf(fp, "seq %08u ", ntohl(xsinfo->seq));
> if (show_stats > 0 || xsinfo->flags) {
> __u8 flags = xsinfo->flags;
>
>
>
Moving to netdev list for more feedback.
Your change has two components:
1. printing sequence number in decimal notation with 0x prefix.
2. doing ntohl().
The first is an obvious bug in the original code. Not sure about
the second. It looks like sequence numbers generated by the kernel
come from xfrm_get_acqseq() which generates sequence numbers in host
byte order. But sequence numbers entered from user space (vi xfrm_seq_parse)
are encoded in network byte order. This looks like a flaw in the original design.
The kernel networking code tries to be careful about documenting network
verus host byte order via the typedef __be32 vs __u32. Given that the kernel
is using __u32 for sequence number in xfrm fairly consistently; my opninon
is that iproute2 should change and go with the kernel practice and
use host byte order.
^ permalink raw reply
* Re: [RFC PATCH 0/4] inet: add second hash table
From: Ben Greear @ 2012-05-30 16:27 UTC (permalink / raw)
To: Eric Dumazet
Cc: Daniel Baluta, Alexandru Copot, davem, gerrit, kuznet, jmorris,
yoshfuji, kaber, netdev, Lucian Grijincu
In-Reply-To: <1338381662.2760.172.camel@edumazet-glaptop>
On 05/30/2012 05:41 AM, Eric Dumazet wrote:
> On Wed, 2012-05-30 at 15:32 +0300, Daniel Baluta wrote:
> UDP case was a bit different, since production machine could really have
> thousand of UDP flows for tunnel terminations.
>
> But for TCP, unless your very specific needs I don't see the real need
> to review 400 lines of patches ?
>
> Nobody but you ever complained of listen() being performance critical
> with 16.000 IP on a machime...
Well, we do similar things and would probably benefit from this change...
If it would help, I'll add these to our kernels and run them through
some of our test cases..but will probably be a week or two at soonest...
Thanks,
Ben
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* Re: [RFC PATCH 4/4] inet: use second hash in inet_csk_get_port
From: Eric Dumazet @ 2012-05-30 16:42 UTC (permalink / raw)
To: Alexandru Copot
Cc: davem, gerrit, kuznet, jmorris, yoshfuji, kaber, netdev,
Daniel Baluta, Lucian Grijincu
In-Reply-To: <1338363410-6562-5-git-send-email-alex.mihai.c@gmail.com>
On Wed, 2012-05-30 at 10:36 +0300, Alexandru Copot wrote:
> diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
> index bc06168..2f589bb 100644
> --- a/include/net/inet_hashtables.h
> +++ b/include/net/inet_hashtables.h
> @@ -81,6 +81,15 @@ struct inet_bind_bucket {
> struct net *ib_net;
> #endif
> unsigned short port;
> + union {
> + struct in6_addr ib_addr_ipv6;
> + struct {
> + __be32 _1;
> + __be32 _2;
> + __be32 _3;
> + __be32 ib_addr_ipv4;
> + };
> + };
> signed short fastreuse;
> int num_owners;
> struct hlist_node node;
Yet another poor choice, adding two holes in this structure.
^ permalink raw reply
* pull request: wireless 2012-05-30
From: John W. Linville @ 2012-05-30 17:13 UTC (permalink / raw)
To: davem; +Cc: linux-wireless, netdev, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 54633 bytes --]
Dave,
Here is a batch of fixes intended for 3.5. They have spent a little
time in linux-next, and for the most part they are reasonably small
and obvious.
Claudio Pisa gives us a one-line fix to correct a check for QoS
NoAck frames.
Dan Carpenter fixes an integer overflow issue in the NFC code.
Emmanuel Grumbach fixes a WARNING related to management of iwlwifi's
Transmit Frame Descriptor rings.
Eyal Shapira fixes some build breakage in the wlcore module when
CONFIG_PM is not defined. Eyal also fixes a mac80211 issue where some
block ack state info wasn't getting handle properly across a suspend.
Felix gives us a load of fixes this time. The ath5k one ensures that
users of multiple virtual interfaces can continue doing so, since
"cfg80211: enforce lack of interface combinations" would otherwise
prevent that. An ath9k fix stops rx dma when stopping tx, preventing
some "Failed to stop Tx DMA!" messages. Another ath9k fix prevents
a use-after-free bug. Felix also updates some ath9k_hw hardware
initialization values, in order to prevent issues with "Tx being
flakey and Rx not working at all" and to avoid stability issues with
AR933X devices.
Grazvydas Ignotas fixes an oops in wl1251 related to enabling irqs.
Hauke Mehrtens provides a brcmfmac fix to avoid a failure to allocate
memory for the device firmware.
Johannes removes some code to support an unavailable batch of firmware
for the iwlwifi devices. This provides much of the iwlwifi bulk
in this pull request. Johannes also provides a fix for an iwlwifi
memory leak.
Meenakshi Venkataraman provides a trio of iwlwifi fixes. One adds a
needed firmware update when BT traffic load changes. Another removes
the use of shadow registers, which was leading to synchronization
problems between the driver and firmware. The last avoids a WARNING
that came when the driver inappropriately sent firmware commands even
when a prerequisite command failed.
Last but not least, Soumik Das provides a mac80211 fix for a race
that resulted in a timeout and a disconnection.
Please let me know if there are problems!
Thanks,
John
---
The following changes since commit 3fdcbd453152329002f12dfda0be90b714458164:
drop_monitor: Add module alias to enable automatic module loading (2012-05-29 22:33:56 -0400)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git for-davem
Claudio Pisa (1):
mac80211: fix flag check for QoS NOACK frames
Dan Carpenter (1):
NFC: potential integer overflow problem in check_crc()
Emmanuel Grumbach (1):
iwlwifi: fix the Transmit Frame Descriptor rings
Eyal Shapira (2):
wlcore: fix undefined symbols when CONFIG_PM is not defined
mac80211: fix ADDBA declined after suspend with wowlan
Felix Fietkau (5):
ath5k: add possible wiphy interface combinations
ath9k: stop rx dma before stopping tx
ath9k: fix a use-after-free-bug when ath_tx_setup_buffer() fails
ath9k_hw: update AR933x initvals to fix issues with high power devices
ath9k_hw: apply internal regulator settings on AR933x
Grazvydas Ignotas (1):
wl1251: fix oops on early interrupt
Hauke Mehrtens (1):
brcmfmac: use vmalloc to allocate mem for the firmware
Johannes Berg (2):
iwlwifi: remove ucode16 option
iwlwifi: fix memory leak if opmode fails to init
John W. Linville (1):
Merge branch 'master' of git://git.kernel.org/.../linville/wireless into for-davem
Meenakshi Venkataraman (3):
iwlwifi: update BT traffic load states correctly
iwlwifi: do not use shadow registers by default
iwlwifi: do not send lq cmd when station add fails
Soumik Das (1):
mac80211: Fix race in checking AP status by sending null frame
drivers/net/wireless/ath/ath5k/base.c | 19 ++
drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 2 +-
drivers/net/wireless/ath/ath9k/ar9003_eeprom.h | 3 +
.../net/wireless/ath/ath9k/ar9330_1p1_initvals.h | 178 ++++++------
drivers/net/wireless/ath/ath9k/hw.c | 3 +
drivers/net/wireless/ath/ath9k/main.c | 7 +-
drivers/net/wireless/ath/ath9k/xmit.c | 16 +-
drivers/net/wireless/brcm80211/brcmfmac/usb.c | 5 +-
drivers/net/wireless/iwlwifi/Kconfig | 8 -
drivers/net/wireless/iwlwifi/Makefile | 1 -
drivers/net/wireless/iwlwifi/iwl-2000.c | 4 +-
drivers/net/wireless/iwlwifi/iwl-6000.c | 6 +-
drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 1 +
drivers/net/wireless/iwlwifi/iwl-agn-sta.c | 2 +-
drivers/net/wireless/iwlwifi/iwl-drv.c | 18 +-
drivers/net/wireless/iwlwifi/iwl-phy-db.c | 288 --------------------
drivers/net/wireless/iwlwifi/iwl-phy-db.h | 129 ---------
drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | 2 +-
drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | 22 +-
drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 4 +-
drivers/net/wireless/ti/wl1251/sdio.c | 2 +-
drivers/net/wireless/ti/wl1251/spi.c | 3 +-
drivers/net/wireless/ti/wlcore/acx.c | 2 +
drivers/net/wireless/ti/wlcore/acx.h | 4 +-
drivers/net/wireless/ti/wlcore/rx.c | 2 +
drivers/nfc/pn544_hci.c | 2 +-
net/mac80211/mlme.c | 3 +-
net/mac80211/tx.c | 2 +-
net/mac80211/util.c | 12 +-
29 files changed, 184 insertions(+), 566 deletions(-)
delete mode 100644 drivers/net/wireless/iwlwifi/iwl-phy-db.c
delete mode 100644 drivers/net/wireless/iwlwifi/iwl-phy-db.h
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 0ba81a6..fbaa309 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -2415,6 +2415,22 @@ ath5k_tx_complete_poll_work(struct work_struct *work)
* Initialization routines *
\*************************/
+static const struct ieee80211_iface_limit if_limits[] = {
+ { .max = 2048, .types = BIT(NL80211_IFTYPE_STATION) },
+ { .max = 4, .types =
+#ifdef CONFIG_MAC80211_MESH
+ BIT(NL80211_IFTYPE_MESH_POINT) |
+#endif
+ BIT(NL80211_IFTYPE_AP) },
+};
+
+static const struct ieee80211_iface_combination if_comb = {
+ .limits = if_limits,
+ .n_limits = ARRAY_SIZE(if_limits),
+ .max_interfaces = 2048,
+ .num_different_channels = 1,
+};
+
int __devinit
ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops)
{
@@ -2436,6 +2452,9 @@ ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops)
BIT(NL80211_IFTYPE_ADHOC) |
BIT(NL80211_IFTYPE_MESH_POINT);
+ hw->wiphy->iface_combinations = &if_comb;
+ hw->wiphy->n_iface_combinations = 1;
+
/* SW support for IBSS_RSN is provided by mac80211 */
hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index ac53d90..dfb0441 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -3809,7 +3809,7 @@ static bool is_pmu_set(struct ath_hw *ah, u32 pmu_reg, int pmu_set)
return true;
}
-static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
+void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
{
int internal_regulator =
ath9k_hw_ar9300_get_eeprom(ah, EEP_INTERNAL_REGULATOR);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
index 2505ac4..8396d15 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
@@ -334,4 +334,7 @@ u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is_2ghz);
unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah,
struct ath9k_channel *chan);
+
+void ar9003_hw_internal_regulator_apply(struct ath_hw *ah);
+
#endif
diff --git a/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h b/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h
index f11d9b2..1bd3a3d 100644
--- a/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h
@@ -1,5 +1,6 @@
/*
- * Copyright (c) 2011 Atheros Communications Inc.
+ * Copyright (c) 2010-2011 Atheros Communications Inc.
+ * Copyright (c) 2011-2012 Qualcomm Atheros Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -18,7 +19,7 @@
#define INITVALS_9330_1P1_H
static const u32 ar9331_1p1_baseband_postamble[][5] = {
- /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
{0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005},
{0x00009820, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e},
{0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
@@ -27,10 +28,10 @@ static const u32 ar9331_1p1_baseband_postamble[][5] = {
{0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c},
{0x00009c00, 0x00000044, 0x00000044, 0x00000044, 0x00000044},
{0x00009e00, 0x0372161e, 0x0372161e, 0x037216a4, 0x037216a4},
- {0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020},
+ {0x00009e04, 0x00202020, 0x00202020, 0x00202020, 0x00202020},
{0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2},
{0x00009e10, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e},
- {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e},
+ {0x00009e14, 0x31365d5e, 0x3136605e, 0x3136605e, 0x31365d5e},
{0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
{0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
@@ -55,7 +56,7 @@ static const u32 ar9331_1p1_baseband_postamble[][5] = {
{0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
- {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071981},
+ {0x0000a2d0, 0x00071982, 0x00071982, 0x00071982, 0x00071982},
{0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a},
{0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x0000ae04, 0x00802020, 0x00802020, 0x00802020, 0x00802020},
@@ -63,7 +64,7 @@ static const u32 ar9331_1p1_baseband_postamble[][5] = {
};
static const u32 ar9331_modes_lowest_ob_db_tx_gain_1p1[][5] = {
- /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
{0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a},
{0x0000a2dc, 0xffff2a52, 0xffff2a52, 0xffff2a52, 0xffff2a52},
{0x0000a2e0, 0xffffcc84, 0xffffcc84, 0xffffcc84, 0xffffcc84},
@@ -155,7 +156,7 @@ static const u32 ar9331_modes_lowest_ob_db_tx_gain_1p1[][5] = {
};
static const u32 ar9331_modes_high_ob_db_tx_gain_1p1[][5] = {
- /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
{0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a},
{0x0000a2dc, 0xffaa9a52, 0xffaa9a52, 0xffaa9a52, 0xffaa9a52},
{0x0000a2e0, 0xffb31c84, 0xffb31c84, 0xffb31c84, 0xffb31c84},
@@ -245,7 +246,7 @@ static const u32 ar9331_modes_high_ob_db_tx_gain_1p1[][5] = {
};
static const u32 ar9331_modes_low_ob_db_tx_gain_1p1[][5] = {
- /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
{0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a},
{0x0000a2dc, 0xffff2a52, 0xffff2a52, 0xffff2a52, 0xffff2a52},
{0x0000a2e0, 0xffffcc84, 0xffffcc84, 0xffffcc84, 0xffffcc84},
@@ -377,14 +378,14 @@ static const u32 ar9331_1p1_radio_core[][2] = {
{0x000160b4, 0x92480040},
{0x000160c0, 0x006db6db},
{0x000160c4, 0x0186db60},
- {0x000160c8, 0x6db6db6c},
+ {0x000160c8, 0x6db4db6c},
{0x000160cc, 0x6de6c300},
{0x000160d0, 0x14500820},
{0x00016100, 0x04cb0001},
{0x00016104, 0xfff80015},
{0x00016108, 0x00080010},
{0x0001610c, 0x00170000},
- {0x00016140, 0x10804000},
+ {0x00016140, 0x10800000},
{0x00016144, 0x01884080},
{0x00016148, 0x000080c0},
{0x00016280, 0x01000015},
@@ -417,7 +418,7 @@ static const u32 ar9331_1p1_radio_core[][2] = {
};
static const u32 ar9331_1p1_soc_postamble[][5] = {
- /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
{0x00007010, 0x00000022, 0x00000022, 0x00000022, 0x00000022},
};
@@ -691,7 +692,7 @@ static const u32 ar9331_1p1_baseband_core[][2] = {
};
static const u32 ar9331_modes_high_power_tx_gain_1p1[][5] = {
- /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
{0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a},
{0x0000a2dc, 0xffff2a52, 0xffff2a52, 0xffff2a52, 0xffff2a52},
{0x0000a2e0, 0xffffcc84, 0xffffcc84, 0xffffcc84, 0xffffcc84},
@@ -783,7 +784,7 @@ static const u32 ar9331_modes_high_power_tx_gain_1p1[][5] = {
};
static const u32 ar9331_1p1_mac_postamble[][5] = {
- /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
{0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
{0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
{0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38},
@@ -973,26 +974,27 @@ static const u32 ar9331_1p1_mac_core[][2] = {
static const u32 ar9331_common_rx_gain_1p1[][2] = {
/* Addr allmodes */
- {0x0000a000, 0x00010000},
- {0x0000a004, 0x00030002},
- {0x0000a008, 0x00050004},
- {0x0000a00c, 0x00810080},
- {0x0000a010, 0x00830082},
- {0x0000a014, 0x01810180},
- {0x0000a018, 0x01830182},
- {0x0000a01c, 0x01850184},
- {0x0000a020, 0x01890188},
- {0x0000a024, 0x018b018a},
- {0x0000a028, 0x018d018c},
- {0x0000a02c, 0x01910190},
- {0x0000a030, 0x01930192},
- {0x0000a034, 0x01950194},
- {0x0000a038, 0x038a0196},
- {0x0000a03c, 0x038c038b},
- {0x0000a040, 0x0390038d},
- {0x0000a044, 0x03920391},
- {0x0000a048, 0x03940393},
- {0x0000a04c, 0x03960395},
+ {0x00009e18, 0x05000000},
+ {0x0000a000, 0x00060005},
+ {0x0000a004, 0x00810080},
+ {0x0000a008, 0x00830082},
+ {0x0000a00c, 0x00850084},
+ {0x0000a010, 0x01820181},
+ {0x0000a014, 0x01840183},
+ {0x0000a018, 0x01880185},
+ {0x0000a01c, 0x018a0189},
+ {0x0000a020, 0x02850284},
+ {0x0000a024, 0x02890288},
+ {0x0000a028, 0x028b028a},
+ {0x0000a02c, 0x03850384},
+ {0x0000a030, 0x03890388},
+ {0x0000a034, 0x038b038a},
+ {0x0000a038, 0x038d038c},
+ {0x0000a03c, 0x03910390},
+ {0x0000a040, 0x03930392},
+ {0x0000a044, 0x03950394},
+ {0x0000a048, 0x00000396},
+ {0x0000a04c, 0x00000000},
{0x0000a050, 0x00000000},
{0x0000a054, 0x00000000},
{0x0000a058, 0x00000000},
@@ -1005,15 +1007,15 @@ static const u32 ar9331_common_rx_gain_1p1[][2] = {
{0x0000a074, 0x00000000},
{0x0000a078, 0x00000000},
{0x0000a07c, 0x00000000},
- {0x0000a080, 0x22222229},
- {0x0000a084, 0x1d1d1d1d},
- {0x0000a088, 0x1d1d1d1d},
- {0x0000a08c, 0x1d1d1d1d},
- {0x0000a090, 0x171d1d1d},
- {0x0000a094, 0x11111717},
- {0x0000a098, 0x00030311},
- {0x0000a09c, 0x00000000},
- {0x0000a0a0, 0x00000000},
+ {0x0000a080, 0x28282828},
+ {0x0000a084, 0x28282828},
+ {0x0000a088, 0x28282828},
+ {0x0000a08c, 0x28282828},
+ {0x0000a090, 0x28282828},
+ {0x0000a094, 0x24242428},
+ {0x0000a098, 0x171e1e1e},
+ {0x0000a09c, 0x02020b0b},
+ {0x0000a0a0, 0x02020202},
{0x0000a0a4, 0x00000000},
{0x0000a0a8, 0x00000000},
{0x0000a0ac, 0x00000000},
@@ -1021,27 +1023,27 @@ static const u32 ar9331_common_rx_gain_1p1[][2] = {
{0x0000a0b4, 0x00000000},
{0x0000a0b8, 0x00000000},
{0x0000a0bc, 0x00000000},
- {0x0000a0c0, 0x001f0000},
- {0x0000a0c4, 0x01000101},
- {0x0000a0c8, 0x011e011f},
- {0x0000a0cc, 0x011c011d},
- {0x0000a0d0, 0x02030204},
- {0x0000a0d4, 0x02010202},
- {0x0000a0d8, 0x021f0200},
- {0x0000a0dc, 0x0302021e},
- {0x0000a0e0, 0x03000301},
- {0x0000a0e4, 0x031e031f},
- {0x0000a0e8, 0x0402031d},
- {0x0000a0ec, 0x04000401},
- {0x0000a0f0, 0x041e041f},
- {0x0000a0f4, 0x0502041d},
- {0x0000a0f8, 0x05000501},
- {0x0000a0fc, 0x051e051f},
- {0x0000a100, 0x06010602},
- {0x0000a104, 0x061f0600},
- {0x0000a108, 0x061d061e},
- {0x0000a10c, 0x07020703},
- {0x0000a110, 0x07000701},
+ {0x0000a0c0, 0x22072208},
+ {0x0000a0c4, 0x22052206},
+ {0x0000a0c8, 0x22032204},
+ {0x0000a0cc, 0x22012202},
+ {0x0000a0d0, 0x221f2200},
+ {0x0000a0d4, 0x221d221e},
+ {0x0000a0d8, 0x33023303},
+ {0x0000a0dc, 0x33003301},
+ {0x0000a0e0, 0x331e331f},
+ {0x0000a0e4, 0x4402331d},
+ {0x0000a0e8, 0x44004401},
+ {0x0000a0ec, 0x441e441f},
+ {0x0000a0f0, 0x55025503},
+ {0x0000a0f4, 0x55005501},
+ {0x0000a0f8, 0x551e551f},
+ {0x0000a0fc, 0x6602551d},
+ {0x0000a100, 0x66006601},
+ {0x0000a104, 0x661e661f},
+ {0x0000a108, 0x7703661d},
+ {0x0000a10c, 0x77017702},
+ {0x0000a110, 0x00007700},
{0x0000a114, 0x00000000},
{0x0000a118, 0x00000000},
{0x0000a11c, 0x00000000},
@@ -1054,26 +1056,26 @@ static const u32 ar9331_common_rx_gain_1p1[][2] = {
{0x0000a138, 0x00000000},
{0x0000a13c, 0x00000000},
{0x0000a140, 0x001f0000},
- {0x0000a144, 0x01000101},
- {0x0000a148, 0x011e011f},
- {0x0000a14c, 0x011c011d},
- {0x0000a150, 0x02030204},
- {0x0000a154, 0x02010202},
- {0x0000a158, 0x021f0200},
- {0x0000a15c, 0x0302021e},
- {0x0000a160, 0x03000301},
- {0x0000a164, 0x031e031f},
- {0x0000a168, 0x0402031d},
- {0x0000a16c, 0x04000401},
- {0x0000a170, 0x041e041f},
- {0x0000a174, 0x0502041d},
- {0x0000a178, 0x05000501},
- {0x0000a17c, 0x051e051f},
- {0x0000a180, 0x06010602},
- {0x0000a184, 0x061f0600},
- {0x0000a188, 0x061d061e},
- {0x0000a18c, 0x07020703},
- {0x0000a190, 0x07000701},
+ {0x0000a144, 0x111f1100},
+ {0x0000a148, 0x111d111e},
+ {0x0000a14c, 0x111b111c},
+ {0x0000a150, 0x22032204},
+ {0x0000a154, 0x22012202},
+ {0x0000a158, 0x221f2200},
+ {0x0000a15c, 0x221d221e},
+ {0x0000a160, 0x33013302},
+ {0x0000a164, 0x331f3300},
+ {0x0000a168, 0x4402331e},
+ {0x0000a16c, 0x44004401},
+ {0x0000a170, 0x441e441f},
+ {0x0000a174, 0x55015502},
+ {0x0000a178, 0x551f5500},
+ {0x0000a17c, 0x6602551e},
+ {0x0000a180, 0x66006601},
+ {0x0000a184, 0x661e661f},
+ {0x0000a188, 0x7703661d},
+ {0x0000a18c, 0x77017702},
+ {0x0000a190, 0x00007700},
{0x0000a194, 0x00000000},
{0x0000a198, 0x00000000},
{0x0000a19c, 0x00000000},
@@ -1100,14 +1102,14 @@ static const u32 ar9331_common_rx_gain_1p1[][2] = {
{0x0000a1f0, 0x00000396},
{0x0000a1f4, 0x00000396},
{0x0000a1f8, 0x00000396},
- {0x0000a1fc, 0x00000196},
+ {0x0000a1fc, 0x00000296},
};
static const u32 ar9331_common_tx_gain_offset1_1[][1] = {
- {0},
- {3},
- {0},
- {0},
+ {0x00000000},
+ {0x00000003},
+ {0x00000000},
+ {0x00000000},
};
static const u32 ar9331_1p1_chansel_xtal_25M[] = {
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index abe05ec..7db1890 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1468,6 +1468,9 @@ static bool ath9k_hw_chip_reset(struct ath_hw *ah,
return false;
ah->chip_fullsleep = false;
+
+ if (AR_SREV_9330(ah))
+ ar9003_hw_internal_regulator_apply(ah);
ath9k_hw_init_pll(ah, chan);
ath9k_hw_set_rfmode(ah, chan);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index dfa78e8..4de4473 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -239,7 +239,7 @@ static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush)
{
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
- bool ret;
+ bool ret = true;
ieee80211_stop_queues(sc->hw);
@@ -250,11 +250,12 @@ static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush)
ath9k_debug_samp_bb_mac(sc);
ath9k_hw_disable_interrupts(ah);
- ret = ath_drain_all_txq(sc, retry_tx);
-
if (!ath_stoprecv(sc))
ret = false;
+ if (!ath_drain_all_txq(sc, retry_tx))
+ ret = false;
+
if (!flush) {
if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
ath_rx_tasklet(sc, 1, true);
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 23eaa1b..d59dd01 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -64,7 +64,8 @@ static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
struct ath_txq *txq,
struct ath_atx_tid *tid,
- struct sk_buff *skb);
+ struct sk_buff *skb,
+ bool dequeue);
enum {
MCS_HT20,
@@ -811,7 +812,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
fi = get_frame_info(skb);
bf = fi->bf;
if (!fi->bf)
- bf = ath_tx_setup_buffer(sc, txq, tid, skb);
+ bf = ath_tx_setup_buffer(sc, txq, tid, skb, true);
if (!bf)
continue;
@@ -1726,7 +1727,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
return;
}
- bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb);
+ bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb, false);
if (!bf)
return;
@@ -1753,7 +1754,7 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
bf = fi->bf;
if (!bf)
- bf = ath_tx_setup_buffer(sc, txq, tid, skb);
+ bf = ath_tx_setup_buffer(sc, txq, tid, skb, false);
if (!bf)
return;
@@ -1814,7 +1815,8 @@ u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate)
static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
struct ath_txq *txq,
struct ath_atx_tid *tid,
- struct sk_buff *skb)
+ struct sk_buff *skb,
+ bool dequeue)
{
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath_frame_info *fi = get_frame_info(skb);
@@ -1863,6 +1865,8 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
return bf;
error:
+ if (dequeue)
+ __skb_unlink(skb, &tid->buf_q);
dev_kfree_skb_any(skb);
return NULL;
}
@@ -1893,7 +1897,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb,
*/
ath_tx_send_ampdu(sc, tid, skb, txctl);
} else {
- bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb);
+ bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb, false);
if (!bf)
return;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
index c5a34ff..a299d42 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
@@ -28,6 +28,7 @@
#include <linux/uaccess.h>
#include <linux/firmware.h>
#include <linux/usb.h>
+#include <linux/vmalloc.h>
#include <net/cfg80211.h>
#include <defs.h>
@@ -1239,7 +1240,7 @@ static int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo)
return -EINVAL;
}
- devinfo->image = kmalloc(fw->size, GFP_ATOMIC); /* plus nvram */
+ devinfo->image = vmalloc(fw->size); /* plus nvram */
if (!devinfo->image)
return -ENOMEM;
@@ -1603,7 +1604,7 @@ static struct usb_driver brcmf_usbdrvr = {
void brcmf_usb_exit(void)
{
usb_deregister(&brcmf_usbdrvr);
- kfree(g_image.data);
+ vfree(g_image.data);
g_image.data = NULL;
g_image.len = 0;
}
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index db6c6e5..2463c06 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -137,11 +137,3 @@ config IWLWIFI_EXPERIMENTAL_MFP
even if the microcode doesn't advertise it.
Say Y only if you want to experiment with MFP.
-
-config IWLWIFI_UCODE16
- bool "support uCode 16.0"
- depends on IWLWIFI
- help
- This option enables support for uCode version 16.0.
-
- Say Y if you want to use 16.0 microcode.
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 406f297..d615eac 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -18,7 +18,6 @@ iwlwifi-objs += iwl-notif-wait.o
iwlwifi-objs += iwl-trans-pcie.o iwl-trans-pcie-rx.o iwl-trans-pcie-tx.o
-iwlwifi-$(CONFIG_IWLWIFI_UCODE16) += iwl-phy-db.o
iwlwifi-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o
iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += iwl-testmode.o
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c
index 7f79341..8133105 100644
--- a/drivers/net/wireless/iwlwifi/iwl-2000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-2000.c
@@ -79,7 +79,7 @@ static const struct iwl_base_params iwl2000_base_params = {
.chain_noise_scale = 1000,
.wd_timeout = IWL_DEF_WD_TIMEOUT,
.max_event_log_size = 512,
- .shadow_reg_enable = true,
+ .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
.hd_v2 = true,
};
@@ -97,7 +97,7 @@ static const struct iwl_base_params iwl2030_base_params = {
.chain_noise_scale = 1000,
.wd_timeout = IWL_LONG_WD_TIMEOUT,
.max_event_log_size = 512,
- .shadow_reg_enable = true,
+ .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
.hd_v2 = true,
};
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 381b02c..19f7ee8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -86,7 +86,7 @@ static const struct iwl_base_params iwl6000_base_params = {
.chain_noise_scale = 1000,
.wd_timeout = IWL_DEF_WD_TIMEOUT,
.max_event_log_size = 512,
- .shadow_reg_enable = true,
+ .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
};
static const struct iwl_base_params iwl6050_base_params = {
@@ -102,7 +102,7 @@ static const struct iwl_base_params iwl6050_base_params = {
.chain_noise_scale = 1500,
.wd_timeout = IWL_DEF_WD_TIMEOUT,
.max_event_log_size = 1024,
- .shadow_reg_enable = true,
+ .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
};
static const struct iwl_base_params iwl6000_g2_base_params = {
@@ -118,7 +118,7 @@ static const struct iwl_base_params iwl6000_g2_base_params = {
.chain_noise_scale = 1000,
.wd_timeout = IWL_LONG_WD_TIMEOUT,
.max_event_log_size = 512,
- .shadow_reg_enable = true,
+ .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
};
static const struct iwl_ht_params iwl6000_ht_params = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 51e1a69..8cebd7c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -884,6 +884,7 @@ static void rs_bt_update_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
if ((priv->bt_traffic_load != priv->last_bt_traffic_load) ||
(priv->bt_full_concurrent != full_concurrent)) {
priv->bt_full_concurrent = full_concurrent;
+ priv->last_bt_traffic_load = priv->bt_traffic_load;
/* Update uCode's rate table. */
tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
index b31584e..aea07aa 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
@@ -772,7 +772,7 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
~IWL_STA_DRIVER_ACTIVE;
priv->stations[i].used &=
~IWL_STA_UCODE_INPROGRESS;
- spin_unlock_bh(&priv->sta_lock);
+ continue;
}
/*
* Rate scaling has already been initialized, send
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index 3c72bad..d742900 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -657,17 +657,17 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
return -EINVAL;
}
-static int alloc_pci_desc(struct iwl_drv *drv,
- struct iwl_firmware_pieces *pieces,
- enum iwl_ucode_type type)
+static int iwl_alloc_ucode(struct iwl_drv *drv,
+ struct iwl_firmware_pieces *pieces,
+ enum iwl_ucode_type type)
{
int i;
for (i = 0;
i < IWL_UCODE_SECTION_MAX && get_sec_size(pieces, type, i);
i++)
if (iwl_alloc_fw_desc(drv, &(drv->fw.img[type].sec[i]),
- get_sec(pieces, type, i)))
- return -1;
+ get_sec(pieces, type, i)))
+ return -ENOMEM;
return 0;
}
@@ -825,8 +825,8 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
* 1) unmodified from disk
* 2) backup cache for save/restore during power-downs */
for (i = 0; i < IWL_UCODE_TYPE_MAX; i++)
- if (alloc_pci_desc(drv, &pieces, i))
- goto err_pci_alloc;
+ if (iwl_alloc_ucode(drv, &pieces, i))
+ goto out_free_fw;
/* Now that we can no longer fail, copy information */
@@ -866,7 +866,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
drv->op_mode = iwl_dvm_ops.start(drv->trans, drv->cfg, &drv->fw);
if (!drv->op_mode)
- goto out_unbind;
+ goto out_free_fw;
return;
@@ -877,7 +877,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
goto out_unbind;
return;
- err_pci_alloc:
+ out_free_fw:
IWL_ERR(drv, "failed to allocate pci memory\n");
iwl_dealloc_ucode(drv);
release_firmware(ucode_raw);
diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.c b/drivers/net/wireless/iwlwifi/iwl-phy-db.c
deleted file mode 100644
index f166955..0000000
--- a/drivers/net/wireless/iwlwifi/iwl-phy-db.c
+++ /dev/null
@@ -1,288 +0,0 @@
-/******************************************************************************
- *
- * This file is provided under a dual BSD/GPLv2 license. When using or
- * redistributing this file, you may do so under either license.
- *
- * GPL LICENSE SUMMARY
- *
- * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
- * USA
- *
- * The full GNU General Public License is included in this distribution
- * in the file called LICENSE.GPL.
- *
- * Contact Information:
- * Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- * BSD LICENSE
- *
- * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *****************************************************************************/
-
-#include <linux/slab.h>
-#include <linux/string.h>
-
-#include "iwl-debug.h"
-#include "iwl-dev.h"
-
-#include "iwl-phy-db.h"
-
-#define CHANNEL_NUM_SIZE 4 /* num of channels in calib_ch size */
-
-struct iwl_phy_db *iwl_phy_db_init(struct device *dev)
-{
- struct iwl_phy_db *phy_db = kzalloc(sizeof(struct iwl_phy_db),
- GFP_KERNEL);
-
- if (!phy_db)
- return phy_db;
-
- phy_db->dev = dev;
-
- /* TODO: add default values of the phy db. */
- return phy_db;
-}
-
-/*
- * get phy db section: returns a pointer to a phy db section specified by
- * type and channel group id.
- */
-static struct iwl_phy_db_entry *
-iwl_phy_db_get_section(struct iwl_phy_db *phy_db,
- enum iwl_phy_db_section_type type,
- u16 chg_id)
-{
- if (!phy_db || type < 0 || type >= IWL_PHY_DB_MAX)
- return NULL;
-
- switch (type) {
- case IWL_PHY_DB_CFG:
- return &phy_db->cfg;
- case IWL_PHY_DB_CALIB_NCH:
- return &phy_db->calib_nch;
- case IWL_PHY_DB_CALIB_CH:
- return &phy_db->calib_ch;
- case IWL_PHY_DB_CALIB_CHG_PAPD:
- if (chg_id < 0 || chg_id >= IWL_NUM_PAPD_CH_GROUPS)
- return NULL;
- return &phy_db->calib_ch_group_papd[chg_id];
- case IWL_PHY_DB_CALIB_CHG_TXP:
- if (chg_id < 0 || chg_id >= IWL_NUM_TXP_CH_GROUPS)
- return NULL;
- return &phy_db->calib_ch_group_txp[chg_id];
- default:
- return NULL;
- }
- return NULL;
-}
-
-static void iwl_phy_db_free_section(struct iwl_phy_db *phy_db,
- enum iwl_phy_db_section_type type,
- u16 chg_id)
-{
- struct iwl_phy_db_entry *entry =
- iwl_phy_db_get_section(phy_db, type, chg_id);
- if (!entry)
- return;
-
- kfree(entry->data);
- entry->data = NULL;
- entry->size = 0;
-}
-
-void iwl_phy_db_free(struct iwl_phy_db *phy_db)
-{
- int i;
-
- if (!phy_db)
- return;
-
- iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CFG, 0);
- iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CALIB_NCH, 0);
- iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CALIB_CH, 0);
- for (i = 0; i < IWL_NUM_PAPD_CH_GROUPS; i++)
- iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CALIB_CHG_PAPD, i);
- for (i = 0; i < IWL_NUM_TXP_CH_GROUPS; i++)
- iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CALIB_CHG_TXP, i);
-
- kfree(phy_db);
-}
-
-int iwl_phy_db_set_section(struct iwl_phy_db *phy_db,
- enum iwl_phy_db_section_type type, u8 *data,
- u16 size, gfp_t alloc_ctx)
-{
- struct iwl_phy_db_entry *entry;
- u16 chg_id = 0;
-
- if (!phy_db)
- return -EINVAL;
-
- if (type == IWL_PHY_DB_CALIB_CHG_PAPD ||
- type == IWL_PHY_DB_CALIB_CHG_TXP)
- chg_id = le16_to_cpup((__le16 *)data);
-
- entry = iwl_phy_db_get_section(phy_db, type, chg_id);
- if (!entry)
- return -EINVAL;
-
- kfree(entry->data);
- entry->data = kmemdup(data, size, alloc_ctx);
- if (!entry->data) {
- entry->size = 0;
- return -ENOMEM;
- }
-
- entry->size = size;
-
- if (type == IWL_PHY_DB_CALIB_CH) {
- phy_db->channel_num = le32_to_cpup((__le32 *)data);
- phy_db->channel_size =
- (size - CHANNEL_NUM_SIZE) / phy_db->channel_num;
- }
-
- return 0;
-}
-
-static int is_valid_channel(u16 ch_id)
-{
- if (ch_id <= 14 ||
- (36 <= ch_id && ch_id <= 64 && ch_id % 4 == 0) ||
- (100 <= ch_id && ch_id <= 140 && ch_id % 4 == 0) ||
- (145 <= ch_id && ch_id <= 165 && ch_id % 4 == 1))
- return 1;
- return 0;
-}
-
-static u8 ch_id_to_ch_index(u16 ch_id)
-{
- if (WARN_ON(!is_valid_channel(ch_id)))
- return 0xff;
-
- if (ch_id <= 14)
- return ch_id - 1;
- if (ch_id <= 64)
- return (ch_id + 20) / 4;
- if (ch_id <= 140)
- return (ch_id - 12) / 4;
- return (ch_id - 13) / 4;
-}
-
-
-static u16 channel_id_to_papd(u16 ch_id)
-{
- if (WARN_ON(!is_valid_channel(ch_id)))
- return 0xff;
-
- if (1 <= ch_id && ch_id <= 14)
- return 0;
- if (36 <= ch_id && ch_id <= 64)
- return 1;
- if (100 <= ch_id && ch_id <= 140)
- return 2;
- return 3;
-}
-
-static u16 channel_id_to_txp(struct iwl_phy_db *phy_db, u16 ch_id)
-{
- struct iwl_phy_db_chg_txp *txp_chg;
- int i;
- u8 ch_index = ch_id_to_ch_index(ch_id);
- if (ch_index == 0xff)
- return 0xff;
-
- for (i = 0; i < IWL_NUM_TXP_CH_GROUPS; i++) {
- txp_chg = (void *)phy_db->calib_ch_group_txp[i].data;
- if (!txp_chg)
- return 0xff;
- /*
- * Looking for the first channel group that its max channel is
- * higher then wanted channel.
- */
- if (le16_to_cpu(txp_chg->max_channel_idx) >= ch_index)
- return i;
- }
- return 0xff;
-}
-
-int iwl_phy_db_get_section_data(struct iwl_phy_db *phy_db,
- enum iwl_phy_db_section_type type, u8 **data,
- u16 *size, u16 ch_id)
-{
- struct iwl_phy_db_entry *entry;
- u32 channel_num;
- u32 channel_size;
- u16 ch_group_id = 0;
- u16 index;
-
- if (!phy_db)
- return -EINVAL;
-
- /* find wanted channel group */
- if (type == IWL_PHY_DB_CALIB_CHG_PAPD)
- ch_group_id = channel_id_to_papd(ch_id);
- else if (type == IWL_PHY_DB_CALIB_CHG_TXP)
- ch_group_id = channel_id_to_txp(phy_db, ch_id);
-
- entry = iwl_phy_db_get_section(phy_db, type, ch_group_id);
- if (!entry)
- return -EINVAL;
-
- if (type == IWL_PHY_DB_CALIB_CH) {
- index = ch_id_to_ch_index(ch_id);
- channel_num = phy_db->channel_num;
- channel_size = phy_db->channel_size;
- if (index >= channel_num) {
- IWL_ERR(phy_db, "Wrong channel number %d", ch_id);
- return -EINVAL;
- }
- *data = entry->data + CHANNEL_NUM_SIZE + index * channel_size;
- *size = channel_size;
- } else {
- *data = entry->data;
- *size = entry->size;
- }
- return 0;
-}
diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.h b/drivers/net/wireless/iwlwifi/iwl-phy-db.h
deleted file mode 100644
index c34c6a9..0000000
--- a/drivers/net/wireless/iwlwifi/iwl-phy-db.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/******************************************************************************
- *
- * This file is provided under a dual BSD/GPLv2 license. When using or
- * redistributing this file, you may do so under either license.
- *
- * GPL LICENSE SUMMARY
- *
- * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
- * USA
- *
- * The full GNU General Public License is included in this distribution
- * in the file called LICENSE.GPL.
- *
- * Contact Information:
- * Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- * BSD LICENSE
- *
- * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *****************************************************************************/
-
-#ifndef __IWL_PHYDB_H__
-#define __IWL_PHYDB_H__
-
-#include <linux/types.h>
-
-#define IWL_NUM_PAPD_CH_GROUPS 4
-#define IWL_NUM_TXP_CH_GROUPS 8
-
-struct iwl_phy_db_entry {
- u16 size;
- u8 *data;
-};
-
-struct iwl_shared;
-
-/**
- * struct iwl_phy_db - stores phy configuration and calibration data.
- *
- * @cfg: phy configuration.
- * @calib_nch: non channel specific calibration data.
- * @calib_ch: channel specific calibration data.
- * @calib_ch_group_papd: calibration data related to papd channel group.
- * @calib_ch_group_txp: calibration data related to tx power chanel group.
- */
-struct iwl_phy_db {
- struct iwl_phy_db_entry cfg;
- struct iwl_phy_db_entry calib_nch;
- struct iwl_phy_db_entry calib_ch;
- struct iwl_phy_db_entry calib_ch_group_papd[IWL_NUM_PAPD_CH_GROUPS];
- struct iwl_phy_db_entry calib_ch_group_txp[IWL_NUM_TXP_CH_GROUPS];
-
- u32 channel_num;
- u32 channel_size;
-
- /* for an access to the logger */
- struct device *dev;
-};
-
-enum iwl_phy_db_section_type {
- IWL_PHY_DB_CFG = 1,
- IWL_PHY_DB_CALIB_NCH,
- IWL_PHY_DB_CALIB_CH,
- IWL_PHY_DB_CALIB_CHG_PAPD,
- IWL_PHY_DB_CALIB_CHG_TXP,
- IWL_PHY_DB_MAX
-};
-
-/* for parsing of tx power channel group data that comes from the firmware*/
-struct iwl_phy_db_chg_txp {
- __le32 space;
- __le16 max_channel_idx;
-} __packed;
-
-struct iwl_phy_db *iwl_phy_db_init(struct device *dev);
-
-void iwl_phy_db_free(struct iwl_phy_db *phy_db);
-
-int iwl_phy_db_set_section(struct iwl_phy_db *phy_db,
- enum iwl_phy_db_section_type type, u8 *data,
- u16 size, gfp_t alloc_ctx);
-
-int iwl_phy_db_get_section_data(struct iwl_phy_db *phy_db,
- enum iwl_phy_db_section_type type, u8 **data,
- u16 *size, u16 ch_id);
-
-#endif /* __IWL_PHYDB_H__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h
index 6213c05..e959207 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h
@@ -347,7 +347,7 @@ void iwl_trans_tx_queue_set_status(struct iwl_trans *trans,
void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, int queue, int fifo,
int sta_id, int tid, int frame_limit, u16 ssn);
void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq,
- int index, enum dma_data_direction dma_dir);
+ enum dma_data_direction dma_dir);
int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index,
struct sk_buff_head *skbs);
int iwl_queue_space(const struct iwl_queue *q);
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
index 21a8a67..a875023 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
@@ -204,33 +204,39 @@ static void iwlagn_unmap_tfd(struct iwl_trans *trans, struct iwl_cmd_meta *meta,
for (i = 1; i < num_tbs; i++)
dma_unmap_single(trans->dev, iwl_tfd_tb_get_addr(tfd, i),
iwl_tfd_tb_get_len(tfd, i), dma_dir);
+
+ tfd->num_tbs = 0;
}
/**
* iwlagn_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr]
* @trans - transport private data
* @txq - tx queue
- * @index - the index of the TFD to be freed
- *@dma_dir - the direction of the DMA mapping
+ * @dma_dir - the direction of the DMA mapping
*
* Does NOT advance any TFD circular buffer read/write indexes
* Does NOT free the TFD itself (which is within circular buffer)
*/
void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq,
- int index, enum dma_data_direction dma_dir)
+ enum dma_data_direction dma_dir)
{
struct iwl_tfd *tfd_tmp = txq->tfds;
+ /* rd_ptr is bounded by n_bd and idx is bounded by n_window */
+ int rd_ptr = txq->q.read_ptr;
+ int idx = get_cmd_index(&txq->q, rd_ptr);
+
lockdep_assert_held(&txq->lock);
- iwlagn_unmap_tfd(trans, &txq->entries[index].meta,
- &tfd_tmp[index], dma_dir);
+ /* We have only q->n_window txq->entries, but we use q->n_bd tfds */
+ iwlagn_unmap_tfd(trans, &txq->entries[idx].meta,
+ &tfd_tmp[rd_ptr], dma_dir);
/* free SKB */
if (txq->entries) {
struct sk_buff *skb;
- skb = txq->entries[index].skb;
+ skb = txq->entries[idx].skb;
/* Can be called from irqs-disabled context
* If skb is not NULL, it means that the whole queue is being
@@ -238,7 +244,7 @@ void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq,
*/
if (skb) {
iwl_op_mode_free_skb(trans->op_mode, skb);
- txq->entries[index].skb = NULL;
+ txq->entries[idx].skb = NULL;
}
}
}
@@ -973,7 +979,7 @@ int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index,
iwlagn_txq_inval_byte_cnt_tbl(trans, txq);
- iwlagn_txq_free_tfd(trans, txq, txq->q.read_ptr, DMA_TO_DEVICE);
+ iwlagn_txq_free_tfd(trans, txq, DMA_TO_DEVICE);
freed++;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
index 2e57161..ec6fb39 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
@@ -435,9 +435,7 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id)
spin_lock_bh(&txq->lock);
while (q->write_ptr != q->read_ptr) {
- /* The read_ptr needs to bound by q->n_window */
- iwlagn_txq_free_tfd(trans, txq, get_cmd_index(q, q->read_ptr),
- dma_dir);
+ iwlagn_txq_free_tfd(trans, txq, dma_dir);
q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
}
spin_unlock_bh(&txq->lock);
diff --git a/drivers/net/wireless/ti/wl1251/sdio.c b/drivers/net/wireless/ti/wl1251/sdio.c
index 1b851f6..e2750a1 100644
--- a/drivers/net/wireless/ti/wl1251/sdio.c
+++ b/drivers/net/wireless/ti/wl1251/sdio.c
@@ -260,6 +260,7 @@ static int wl1251_sdio_probe(struct sdio_func *func,
}
if (wl->irq) {
+ irq_set_status_flags(wl->irq, IRQ_NOAUTOEN);
ret = request_irq(wl->irq, wl1251_line_irq, 0, "wl1251", wl);
if (ret < 0) {
wl1251_error("request_irq() failed: %d", ret);
@@ -267,7 +268,6 @@ static int wl1251_sdio_probe(struct sdio_func *func,
}
irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
- disable_irq(wl->irq);
wl1251_sdio_ops.enable_irq = wl1251_enable_line_irq;
wl1251_sdio_ops.disable_irq = wl1251_disable_line_irq;
diff --git a/drivers/net/wireless/ti/wl1251/spi.c b/drivers/net/wireless/ti/wl1251/spi.c
index 6248c35..87f6305 100644
--- a/drivers/net/wireless/ti/wl1251/spi.c
+++ b/drivers/net/wireless/ti/wl1251/spi.c
@@ -281,6 +281,7 @@ static int __devinit wl1251_spi_probe(struct spi_device *spi)
wl->use_eeprom = pdata->use_eeprom;
+ irq_set_status_flags(wl->irq, IRQ_NOAUTOEN);
ret = request_irq(wl->irq, wl1251_irq, 0, DRIVER_NAME, wl);
if (ret < 0) {
wl1251_error("request_irq() failed: %d", ret);
@@ -289,8 +290,6 @@ static int __devinit wl1251_spi_probe(struct spi_device *spi)
irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
- disable_irq(wl->irq);
-
ret = wl1251_init_ieee80211(wl);
if (ret)
goto out_irq;
diff --git a/drivers/net/wireless/ti/wlcore/acx.c b/drivers/net/wireless/ti/wlcore/acx.c
index 509aa88..f3d6fa5 100644
--- a/drivers/net/wireless/ti/wlcore/acx.c
+++ b/drivers/net/wireless/ti/wlcore/acx.c
@@ -1715,6 +1715,7 @@ out:
}
+#ifdef CONFIG_PM
/* Set the global behaviour of RX filters - On/Off + default action */
int wl1271_acx_default_rx_filter_enable(struct wl1271 *wl, bool enable,
enum rx_filter_action action)
@@ -1794,3 +1795,4 @@ out:
kfree(acx);
return ret;
}
+#endif /* CONFIG_PM */
diff --git a/drivers/net/wireless/ti/wlcore/acx.h b/drivers/net/wireless/ti/wlcore/acx.h
index 8106b2e..e6a7486 100644
--- a/drivers/net/wireless/ti/wlcore/acx.h
+++ b/drivers/net/wireless/ti/wlcore/acx.h
@@ -1330,9 +1330,11 @@ int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr);
int wl1271_acx_fm_coex(struct wl1271 *wl);
int wl12xx_acx_set_rate_mgmt_params(struct wl1271 *wl);
int wl12xx_acx_config_hangover(struct wl1271 *wl);
+
+#ifdef CONFIG_PM
int wl1271_acx_default_rx_filter_enable(struct wl1271 *wl, bool enable,
enum rx_filter_action action);
int wl1271_acx_set_rx_filter(struct wl1271 *wl, u8 index, bool enable,
struct wl12xx_rx_filter *filter);
-
+#endif /* CONFIG_PM */
#endif /* __WL1271_ACX_H__ */
diff --git a/drivers/net/wireless/ti/wlcore/rx.c b/drivers/net/wireless/ti/wlcore/rx.c
index 1f1d948..d6a3c6b 100644
--- a/drivers/net/wireless/ti/wlcore/rx.c
+++ b/drivers/net/wireless/ti/wlcore/rx.c
@@ -279,6 +279,7 @@ void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status *status)
wl12xx_rearm_rx_streaming(wl, active_hlids);
}
+#ifdef CONFIG_PM
int wl1271_rx_filter_enable(struct wl1271 *wl,
int index, bool enable,
struct wl12xx_rx_filter *filter)
@@ -314,3 +315,4 @@ void wl1271_rx_filter_clear_all(struct wl1271 *wl)
wl1271_rx_filter_enable(wl, i, 0, NULL);
}
}
+#endif /* CONFIG_PM */
diff --git a/drivers/nfc/pn544_hci.c b/drivers/nfc/pn544_hci.c
index 46f4a9f..281f18c 100644
--- a/drivers/nfc/pn544_hci.c
+++ b/drivers/nfc/pn544_hci.c
@@ -232,7 +232,7 @@ static int pn544_hci_i2c_write(struct i2c_client *client, u8 *buf, int len)
static int check_crc(u8 *buf, int buflen)
{
- u8 len;
+ int len;
u16 crc;
len = buf[0] + 1;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index b3b3c26..04c3063 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1522,6 +1522,8 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
* anymore. The timeout will be reset if the frame is ACKed by
* the AP.
*/
+ ifmgd->probe_send_count++;
+
if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) {
ifmgd->nullfunc_failed = false;
ieee80211_send_nullfunc(sdata->local, sdata, 0);
@@ -1538,7 +1540,6 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
0, (u32) -1, true, false);
}
- ifmgd->probe_send_count++;
ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms);
run_again(ifmgd, ifmgd->probe_timeout);
if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 5f827a6..847215b 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -153,7 +153,7 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx,
/* Don't calculate ACKs for QoS Frames with NoAck Policy set */
if (ieee80211_is_data_qos(hdr->frame_control) &&
- *(ieee80211_get_qos_ctl(hdr)) | IEEE80211_QOS_CTL_ACK_POLICY_NOACK)
+ *(ieee80211_get_qos_ctl(hdr)) & IEEE80211_QOS_CTL_ACK_POLICY_NOACK)
dur = 0;
else
/* Time needed to transmit ACK
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 22f2216..a44c680 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1371,6 +1371,12 @@ int ieee80211_reconfig(struct ieee80211_local *local)
}
}
+ /* add back keys */
+ list_for_each_entry(sdata, &local->interfaces, list)
+ if (ieee80211_sdata_running(sdata))
+ ieee80211_enable_keys(sdata);
+
+ wake_up:
/*
* Clear the WLAN_STA_BLOCK_BA flag so new aggregation
* sessions can be established after a resume.
@@ -1392,12 +1398,6 @@ int ieee80211_reconfig(struct ieee80211_local *local)
mutex_unlock(&local->sta_mtx);
}
- /* add back keys */
- list_for_each_entry(sdata, &local->interfaces, list)
- if (ieee80211_sdata_running(sdata))
- ieee80211_enable_keys(sdata);
-
- wake_up:
ieee80211_wake_queues_by_reason(hw,
IEEE80211_QUEUE_STOP_REASON_SUSPEND);
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply related
* Re: [RFC PATCH 4/4] inet: use second hash in inet_csk_get_port
From: Eric Dumazet @ 2012-05-30 17:20 UTC (permalink / raw)
To: Alexandru Copot
Cc: davem, gerrit, kuznet, jmorris, yoshfuji, kaber, netdev,
Daniel Baluta, Lucian Grijincu
In-Reply-To: <1338363410-6562-5-git-send-email-alex.mihai.c@gmail.com>
On Wed, 2012-05-30 at 10:36 +0300, Alexandru Copot wrote:
> +struct inet_bind_bucket *
> +inet4_find_bind_buckets(struct sock *sk,
> + unsigned short port,
> + struct inet_bind_hashbucket **p_bhead,
> + struct inet_bind_hashbucket **p_portaddr_bhead)
> +{
> + struct net *net = sock_net(sk);
> + struct inet_hashinfo *hinfo = sk->sk_prot->h.hashinfo;
> + struct inet_bind_bucket *tb = NULL;
> + struct hlist_node *node;
> +
> + struct inet_bind_hashbucket *bhead, *portaddr_bhead, *portaddrany_bhead;
> + bhead = &hinfo->bhash[inet_bhashfn(net, port, hinfo->bhash_size)];
> + portaddr_bhead = inet4_portaddr_hashbucket(hinfo, net,
> + sk_rcv_saddr(sk), port);
> + portaddrany_bhead = inet4_portaddr_hashbucket(hinfo, net,
> + INADDR_ANY, port);
> +
> + *p_portaddr_bhead = portaddr_bhead;
> + *p_bhead = bhead;
> +
> + /*
> + * prevent dead locks by always taking locks in a fixed order:
> + * - always take the port-only lock first. This is done because in some
> + * other places this is the lock taken, being folllowed in only some
> + * cases by the portaddr lock.
> + * - between portaddr and portaddrany always choose the one with the
> + * lower address. Unlock ordering is not important, as long as the
> + * locking order is consistent.
> + * - make sure to not take the same lock twice
> + */
> + spin_lock(&bhead->lock);
> + if (portaddr_bhead > portaddrany_bhead) {
> + spin_lock(&portaddrany_bhead->lock);
> + spin_lock(&portaddr_bhead->lock);
> + } else if (portaddr_bhead < portaddrany_bhead) {
> + spin_lock(&portaddr_bhead->lock);
> + spin_lock(&portaddrany_bhead->lock);
> + } else {
> + spin_lock(&portaddr_bhead->lock);
> + }
> +
> + if (sk_rcv_saddr(sk) != INADDR_ANY) {
> + struct inet_bind_hashbucket *_head;
> +
> + _head = portaddr_bhead;
> + if (bhead->count < portaddr_bhead->count) {
> + _head = bhead;
> + inet_bind_bucket_for_each(tb, node, &_head->chain)
> + if ((net_eq(ib_net(tb), net)) &&
> + (tb->port == port) &&
> + (tb->ib_addr_ipv4 == sk_rcv_saddr(sk)))
> + goto found;
> + } else {
> + inet_portaddr_bind_bucket_for_each(tb, node, &_head->chain)
> + if ((net_eq(ib_net(tb), net)) &&
> + (tb->port == port) &&
> + (tb->ib_addr_ipv4 == sk_rcv_saddr(sk)))
> + goto found;
> + }
> + _head = portaddrany_bhead;
> + if (bhead->count < portaddrany_bhead->count) {
> + _head = bhead;
> + inet_bind_bucket_for_each(tb, node, &_head->chain)
> + if ((ib_net(tb) == net) &&
> + (tb->port == port) &&
> + (tb->ib_addr_ipv4 == INADDR_ANY))
> + goto found;
> + } else {
> + inet_portaddr_bind_bucket_for_each(tb, node, &_head->chain)
> + if ((ib_net(tb) == net) &&
> + (tb->port == port) &&
> + (tb->ib_addr_ipv4 == INADDR_ANY))
> + goto found;
> + }
> + } else {
> + inet_bind_bucket_for_each(tb, node, &bhead->chain)
> + if ((ib_net(tb) == net) && (tb->port == port))
> + goto found;
> + }
> +
> + tb = NULL;
> +found:
> + if (portaddr_bhead != portaddrany_bhead)
> + spin_unlock(&portaddrany_bhead->lock);
> +
> + /* the other locks remain taken, as the caller
> + * may want to change the hash tabels */
> + return tb;
> +}
> +
> +
How this is going to work with IPv6 sockets in the middle of the
chains ?
Also, comments are not properly formatted, they should all look like :
/* the other locks remain taken, as the caller
* may want to change the hash tables
*/
And finally, make sure LOCKDEP is happy with your locking code.
^ 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