* [PATCH net-next v2] bridge: multicast to unicast
From: Linus Lüssing @ 2017-01-17 19:59 UTC (permalink / raw)
To: netdev
Cc: David S . Miller, Stephen Hemminger, Felix Fietkau,
Nikolay Aleksandrov, bridge, linux-kernel, linux-wireless,
Linus Lüssing
From: Felix Fietkau <nbd@nbd.name>
Implements an optional, per bridge port flag and feature to deliver
multicast packets to any host on the according port via unicast
individually. This is done by copying the packet per host and
changing the multicast destination MAC to a unicast one accordingly.
multicast-to-unicast works on top of the multicast snooping feature of
the bridge. Which means unicast copies are only delivered to hosts which
are interested in it and signalized this via IGMP/MLD reports
previously.
This feature is intended for interface types which have a more reliable
and/or efficient way to deliver unicast packets than broadcast ones
(e.g. wifi).
However, it should only be enabled on interfaces where no IGMPv2/MLDv1
report suppression takes place. This feature is disabled by default.
The initial patch and idea is from Felix Fietkau.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
[linus.luessing@c0d3.blue: various bug + style fixes, commit message]
Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
---
This feature is used and enabled by default in OpenWRT and LEDE for AP
interfaces for more than a year now to allow both a more robust multicast
delivery and multicast at higher rates (e.g. multicast streaming).
In OpenWRT/LEDE the IGMP/MLD report suppression issue is overcome by
the network daemon enabling AP isolation and by that separating all STAs.
Delivery of STA-to-STA IP mulitcast is made possible again by
enabling and utilizing the bridge hairpin mode, which considers the
incoming port as a potential outgoing port, too.
Hairpin-mode is performed after multicast snooping, therefore leading to
only deliver reports to STAs running a multicast router.
Changes in v2:
* netlink support (thanks Nik!)
* fixed switching between multicast_to_unicast on/off
-> even after toggling an already existing entry would
stale in its mode and would never be replaced
-> new extra check in br_port_group_equal)
* reduced checks in br_multicast_flood() from two to one
to address fast-path concerns (thanks Nik!)
* rev-christmas tree ordering (thanks Nik!)
* removed "net_bridge_port_group::unicast", using
::flags instead (thanks Nik!)
* BR_MULTICAST_TO_UCAST -> BR_MULTICAST_TO_UNICAST
(BR_MULTICAST_FLAST_LEAVE has the same length anyway)
* simplified maybe_deliver_addr()
(no return, no "prev" paramater -> was a NOP anyway)
* added "From: Felix Fietkau [...]"
* added "Signed-off-by: Felix Fietkau [...]"
---
include/linux/if_bridge.h | 1 +
include/uapi/linux/if_link.h | 1 +
net/bridge/br_forward.c | 37 ++++++++++++++++-
net/bridge/br_mdb.c | 2 +-
net/bridge/br_multicast.c | 96 ++++++++++++++++++++++++++++++++------------
net/bridge/br_netlink.c | 5 +++
net/bridge/br_private.h | 8 ++--
net/bridge/br_sysfs_if.c | 2 +
8 files changed, 121 insertions(+), 31 deletions(-)
diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h
index c6587c0..debc9d5 100644
--- a/include/linux/if_bridge.h
+++ b/include/linux/if_bridge.h
@@ -46,6 +46,7 @@ struct br_ip_list {
#define BR_LEARNING_SYNC BIT(9)
#define BR_PROXYARP_WIFI BIT(10)
#define BR_MCAST_FLOOD BIT(11)
+#define BR_MULTICAST_TO_UNICAST BIT(12)
#define BR_DEFAULT_AGEING_TIME (300 * HZ)
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 6b13e59..4e59565 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -321,6 +321,7 @@ enum {
IFLA_BRPORT_MULTICAST_ROUTER,
IFLA_BRPORT_PAD,
IFLA_BRPORT_MCAST_FLOOD,
+ IFLA_BRPORT_MCAST_TO_UCAST,
__IFLA_BRPORT_MAX
};
#define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c
index 7cb41ae..75d041e 100644
--- a/net/bridge/br_forward.c
+++ b/net/bridge/br_forward.c
@@ -174,6 +174,29 @@ static struct net_bridge_port *maybe_deliver(
return p;
}
+static void maybe_deliver_addr(struct net_bridge_port *p, struct sk_buff *skb,
+ const unsigned char *addr, bool local_orig)
+{
+ struct net_device *dev = BR_INPUT_SKB_CB(skb)->brdev;
+ const unsigned char *src = eth_hdr(skb)->h_source;
+
+ if (!should_deliver(p, skb))
+ return;
+
+ /* Even with hairpin, no soliloquies - prevent breaking IPv6 DAD */
+ if (skb->dev == p->dev && ether_addr_equal(src, addr))
+ return;
+
+ skb = skb_copy(skb, GFP_ATOMIC);
+ if (!skb) {
+ dev->stats.tx_dropped++;
+ return;
+ }
+
+ memcpy(eth_hdr(skb)->h_dest, addr, ETH_ALEN);
+ __br_forward(p, skb, local_orig);
+}
+
/* called under rcu_read_lock */
void br_flood(struct net_bridge *br, struct sk_buff *skb,
enum br_pkt_type pkt_type, bool local_rcv, bool local_orig)
@@ -241,10 +264,20 @@ void br_multicast_flood(struct net_bridge_mdb_entry *mdst,
rport = rp ? hlist_entry(rp, struct net_bridge_port, rlist) :
NULL;
- port = (unsigned long)lport > (unsigned long)rport ?
- lport : rport;
+ if ((unsigned long)lport > (unsigned long)rport) {
+ if (p->flags & MDB_PG_FLAGS_MCAST_TO_UCAST) {
+ maybe_deliver_addr(lport, skb, p->eth_addr,
+ local_orig);
+ goto delivered;
+ }
+
+ port = lport;
+ } else {
+ port = rport;
+ }
prev = maybe_deliver(prev, port, skb, local_orig);
+delivered:
if (IS_ERR(prev))
goto out;
if (prev == port)
diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c
index 7dbc80d..056e6ac 100644
--- a/net/bridge/br_mdb.c
+++ b/net/bridge/br_mdb.c
@@ -531,7 +531,7 @@ static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port,
break;
}
- p = br_multicast_new_port_group(port, group, *pp, state);
+ p = br_multicast_new_port_group(port, group, *pp, state, NULL);
if (unlikely(!p))
return -ENOMEM;
rcu_assign_pointer(*pp, p);
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index b30e77e..b127bb7 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -43,12 +43,14 @@ static void br_multicast_add_router(struct net_bridge *br,
static void br_ip4_multicast_leave_group(struct net_bridge *br,
struct net_bridge_port *port,
__be32 group,
- __u16 vid);
+ __u16 vid,
+ const unsigned char *src);
+
#if IS_ENABLED(CONFIG_IPV6)
static void br_ip6_multicast_leave_group(struct net_bridge *br,
struct net_bridge_port *port,
const struct in6_addr *group,
- __u16 vid);
+ __u16 vid, const unsigned char *src);
#endif
unsigned int br_mdb_rehash_seq;
@@ -711,7 +713,8 @@ struct net_bridge_port_group *br_multicast_new_port_group(
struct net_bridge_port *port,
struct br_ip *group,
struct net_bridge_port_group __rcu *next,
- unsigned char flags)
+ unsigned char flags,
+ const unsigned char *src)
{
struct net_bridge_port_group *p;
@@ -726,12 +729,39 @@ struct net_bridge_port_group *br_multicast_new_port_group(
hlist_add_head(&p->mglist, &port->mglist);
setup_timer(&p->timer, br_multicast_port_group_expired,
(unsigned long)p);
+
+ if ((port->flags & BR_MULTICAST_TO_UNICAST) && src) {
+ memcpy(p->eth_addr, src, ETH_ALEN);
+ p->flags |= MDB_PG_FLAGS_MCAST_TO_UCAST;
+ }
+
return p;
}
+static bool br_port_group_equal(struct net_bridge_port_group *p,
+ struct net_bridge_port *port,
+ const unsigned char *src)
+{
+ if (p->port != port)
+ return false;
+
+ if (!(p->flags & MDB_PG_FLAGS_MCAST_TO_UCAST) !=
+ !(port->flags & BR_MULTICAST_TO_UNICAST))
+ return false;
+
+ if (!(p->flags & MDB_PG_FLAGS_MCAST_TO_UCAST))
+ return true;
+
+ if (!src)
+ return false;
+
+ return ether_addr_equal(src, p->eth_addr);
+}
+
static int br_multicast_add_group(struct net_bridge *br,
struct net_bridge_port *port,
- struct br_ip *group)
+ struct br_ip *group,
+ const unsigned char *src)
{
struct net_bridge_port_group __rcu **pp;
struct net_bridge_port_group *p;
@@ -758,13 +788,13 @@ static int br_multicast_add_group(struct net_bridge *br,
for (pp = &mp->ports;
(p = mlock_dereference(*pp, br)) != NULL;
pp = &p->next) {
- if (p->port == port)
+ if (br_port_group_equal(p, port, src))
goto found;
if ((unsigned long)p->port < (unsigned long)port)
break;
}
- p = br_multicast_new_port_group(port, group, *pp, 0);
+ p = br_multicast_new_port_group(port, group, *pp, 0, src);
if (unlikely(!p))
goto err;
rcu_assign_pointer(*pp, p);
@@ -783,7 +813,8 @@ static int br_multicast_add_group(struct net_bridge *br,
static int br_ip4_multicast_add_group(struct net_bridge *br,
struct net_bridge_port *port,
__be32 group,
- __u16 vid)
+ __u16 vid,
+ const unsigned char *src)
{
struct br_ip br_group;
@@ -794,14 +825,15 @@ static int br_ip4_multicast_add_group(struct net_bridge *br,
br_group.proto = htons(ETH_P_IP);
br_group.vid = vid;
- return br_multicast_add_group(br, port, &br_group);
+ return br_multicast_add_group(br, port, &br_group, src);
}
#if IS_ENABLED(CONFIG_IPV6)
static int br_ip6_multicast_add_group(struct net_bridge *br,
struct net_bridge_port *port,
const struct in6_addr *group,
- __u16 vid)
+ __u16 vid,
+ const unsigned char *src)
{
struct br_ip br_group;
@@ -812,7 +844,7 @@ static int br_ip6_multicast_add_group(struct net_bridge *br,
br_group.proto = htons(ETH_P_IPV6);
br_group.vid = vid;
- return br_multicast_add_group(br, port, &br_group);
+ return br_multicast_add_group(br, port, &br_group, src);
}
#endif
@@ -1081,6 +1113,7 @@ static int br_ip4_multicast_igmp3_report(struct net_bridge *br,
struct sk_buff *skb,
u16 vid)
{
+ const unsigned char *src;
struct igmpv3_report *ih;
struct igmpv3_grec *grec;
int i;
@@ -1121,12 +1154,14 @@ static int br_ip4_multicast_igmp3_report(struct net_bridge *br,
continue;
}
+ src = eth_hdr(skb)->h_source;
if ((type == IGMPV3_CHANGE_TO_INCLUDE ||
type == IGMPV3_MODE_IS_INCLUDE) &&
ntohs(grec->grec_nsrcs) == 0) {
- br_ip4_multicast_leave_group(br, port, group, vid);
+ br_ip4_multicast_leave_group(br, port, group, vid, src);
} else {
- err = br_ip4_multicast_add_group(br, port, group, vid);
+ err = br_ip4_multicast_add_group(br, port, group, vid,
+ src);
if (err)
break;
}
@@ -1141,6 +1176,7 @@ static int br_ip6_multicast_mld2_report(struct net_bridge *br,
struct sk_buff *skb,
u16 vid)
{
+ const unsigned char *src = eth_hdr(skb)->h_source;
struct icmp6hdr *icmp6h;
struct mld2_grec *grec;
int i;
@@ -1192,10 +1228,11 @@ static int br_ip6_multicast_mld2_report(struct net_bridge *br,
grec->grec_type == MLD2_MODE_IS_INCLUDE) &&
ntohs(*nsrcs) == 0) {
br_ip6_multicast_leave_group(br, port, &grec->grec_mca,
- vid);
+ vid, src);
} else {
err = br_ip6_multicast_add_group(br, port,
- &grec->grec_mca, vid);
+ &grec->grec_mca, vid,
+ src);
if (err)
break;
}
@@ -1511,7 +1548,8 @@ br_multicast_leave_group(struct net_bridge *br,
struct net_bridge_port *port,
struct br_ip *group,
struct bridge_mcast_other_query *other_query,
- struct bridge_mcast_own_query *own_query)
+ struct bridge_mcast_own_query *own_query,
+ const unsigned char *src)
{
struct net_bridge_mdb_htable *mdb;
struct net_bridge_mdb_entry *mp;
@@ -1535,7 +1573,7 @@ br_multicast_leave_group(struct net_bridge *br,
for (pp = &mp->ports;
(p = mlock_dereference(*pp, br)) != NULL;
pp = &p->next) {
- if (p->port != port)
+ if (!br_port_group_equal(p, port, src))
continue;
rcu_assign_pointer(*pp, p->next);
@@ -1566,7 +1604,7 @@ br_multicast_leave_group(struct net_bridge *br,
for (p = mlock_dereference(mp->ports, br);
p != NULL;
p = mlock_dereference(p->next, br)) {
- if (p->port != port)
+ if (!br_port_group_equal(p, port, src))
continue;
if (!hlist_unhashed(&p->mglist) &&
@@ -1617,7 +1655,8 @@ br_multicast_leave_group(struct net_bridge *br,
static void br_ip4_multicast_leave_group(struct net_bridge *br,
struct net_bridge_port *port,
__be32 group,
- __u16 vid)
+ __u16 vid,
+ const unsigned char *src)
{
struct br_ip br_group;
struct bridge_mcast_own_query *own_query;
@@ -1632,14 +1671,15 @@ static void br_ip4_multicast_leave_group(struct net_bridge *br,
br_group.vid = vid;
br_multicast_leave_group(br, port, &br_group, &br->ip4_other_query,
- own_query);
+ own_query, src);
}
#if IS_ENABLED(CONFIG_IPV6)
static void br_ip6_multicast_leave_group(struct net_bridge *br,
struct net_bridge_port *port,
const struct in6_addr *group,
- __u16 vid)
+ __u16 vid,
+ const unsigned char *src)
{
struct br_ip br_group;
struct bridge_mcast_own_query *own_query;
@@ -1654,7 +1694,7 @@ static void br_ip6_multicast_leave_group(struct net_bridge *br,
br_group.vid = vid;
br_multicast_leave_group(br, port, &br_group, &br->ip6_other_query,
- own_query);
+ own_query, src);
}
#endif
@@ -1712,6 +1752,7 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br,
u16 vid)
{
struct sk_buff *skb_trimmed = NULL;
+ const unsigned char *src;
struct igmphdr *ih;
int err;
@@ -1731,13 +1772,14 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br,
}
ih = igmp_hdr(skb);
+ src = eth_hdr(skb)->h_source;
BR_INPUT_SKB_CB(skb)->igmp = ih->type;
switch (ih->type) {
case IGMP_HOST_MEMBERSHIP_REPORT:
case IGMPV2_HOST_MEMBERSHIP_REPORT:
BR_INPUT_SKB_CB(skb)->mrouters_only = 1;
- err = br_ip4_multicast_add_group(br, port, ih->group, vid);
+ err = br_ip4_multicast_add_group(br, port, ih->group, vid, src);
break;
case IGMPV3_HOST_MEMBERSHIP_REPORT:
err = br_ip4_multicast_igmp3_report(br, port, skb_trimmed, vid);
@@ -1746,7 +1788,7 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br,
err = br_ip4_multicast_query(br, port, skb_trimmed, vid);
break;
case IGMP_HOST_LEAVE_MESSAGE:
- br_ip4_multicast_leave_group(br, port, ih->group, vid);
+ br_ip4_multicast_leave_group(br, port, ih->group, vid, src);
break;
}
@@ -1766,6 +1808,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
u16 vid)
{
struct sk_buff *skb_trimmed = NULL;
+ const unsigned char *src;
struct mld_msg *mld;
int err;
@@ -1785,8 +1828,10 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
switch (mld->mld_type) {
case ICMPV6_MGM_REPORT:
+ src = eth_hdr(skb)->h_source;
BR_INPUT_SKB_CB(skb)->mrouters_only = 1;
- err = br_ip6_multicast_add_group(br, port, &mld->mld_mca, vid);
+ err = br_ip6_multicast_add_group(br, port, &mld->mld_mca, vid,
+ src);
break;
case ICMPV6_MLD2_REPORT:
err = br_ip6_multicast_mld2_report(br, port, skb_trimmed, vid);
@@ -1795,7 +1840,8 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
err = br_ip6_multicast_query(br, port, skb_trimmed, vid);
break;
case ICMPV6_MGM_REDUCTION:
- br_ip6_multicast_leave_group(br, port, &mld->mld_mca, vid);
+ src = eth_hdr(skb)->h_source;
+ br_ip6_multicast_leave_group(br, port, &mld->mld_mca, vid, src);
break;
}
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index 71c7453..6c087cd 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -123,6 +123,7 @@ static inline size_t br_port_info_size(void)
+ nla_total_size(1) /* IFLA_BRPORT_GUARD */
+ nla_total_size(1) /* IFLA_BRPORT_PROTECT */
+ nla_total_size(1) /* IFLA_BRPORT_FAST_LEAVE */
+ + nla_total_size(1) /* IFLA_BRPORT_MCAST_TO_UCAST */
+ nla_total_size(1) /* IFLA_BRPORT_LEARNING */
+ nla_total_size(1) /* IFLA_BRPORT_UNICAST_FLOOD */
+ nla_total_size(1) /* IFLA_BRPORT_PROXYARP */
@@ -173,6 +174,8 @@ static int br_port_fill_attrs(struct sk_buff *skb,
!!(p->flags & BR_ROOT_BLOCK)) ||
nla_put_u8(skb, IFLA_BRPORT_FAST_LEAVE,
!!(p->flags & BR_MULTICAST_FAST_LEAVE)) ||
+ nla_put_u8(skb, IFLA_BRPORT_MCAST_TO_UCAST,
+ !!(p->flags & BR_MULTICAST_TO_UNICAST)) ||
nla_put_u8(skb, IFLA_BRPORT_LEARNING, !!(p->flags & BR_LEARNING)) ||
nla_put_u8(skb, IFLA_BRPORT_UNICAST_FLOOD,
!!(p->flags & BR_FLOOD)) ||
@@ -586,6 +589,7 @@ static const struct nla_policy br_port_policy[IFLA_BRPORT_MAX + 1] = {
[IFLA_BRPORT_PROXYARP] = { .type = NLA_U8 },
[IFLA_BRPORT_PROXYARP_WIFI] = { .type = NLA_U8 },
[IFLA_BRPORT_MULTICAST_ROUTER] = { .type = NLA_U8 },
+ [IFLA_BRPORT_MCAST_TO_UCAST] = { .type = NLA_U8 },
};
/* Change the state of the port and notify spanning tree */
@@ -636,6 +640,7 @@ static int br_setport(struct net_bridge_port *p, struct nlattr *tb[])
br_set_port_flag(p, tb, IFLA_BRPORT_LEARNING, BR_LEARNING);
br_set_port_flag(p, tb, IFLA_BRPORT_UNICAST_FLOOD, BR_FLOOD);
br_set_port_flag(p, tb, IFLA_BRPORT_MCAST_FLOOD, BR_MCAST_FLOOD);
+ br_set_port_flag(p, tb, IFLA_BRPORT_MCAST_TO_UCAST, BR_MULTICAST_TO_UNICAST);
br_set_port_flag(p, tb, IFLA_BRPORT_PROXYARP, BR_PROXYARP);
br_set_port_flag(p, tb, IFLA_BRPORT_PROXYARP_WIFI, BR_PROXYARP_WIFI);
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 8ce621e..f7db79f 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -166,8 +166,9 @@ struct net_bridge_fdb_entry
struct rcu_head rcu;
};
-#define MDB_PG_FLAGS_PERMANENT BIT(0)
-#define MDB_PG_FLAGS_OFFLOAD BIT(1)
+#define MDB_PG_FLAGS_PERMANENT BIT(0)
+#define MDB_PG_FLAGS_OFFLOAD BIT(1)
+#define MDB_PG_FLAGS_MCAST_TO_UCAST BIT(2)
struct net_bridge_port_group {
struct net_bridge_port *port;
@@ -177,6 +178,7 @@ struct net_bridge_port_group {
struct timer_list timer;
struct br_ip addr;
unsigned char flags;
+ unsigned char eth_addr[ETH_ALEN];
};
struct net_bridge_mdb_entry
@@ -599,7 +601,7 @@ void br_multicast_free_pg(struct rcu_head *head);
struct net_bridge_port_group *
br_multicast_new_port_group(struct net_bridge_port *port, struct br_ip *group,
struct net_bridge_port_group __rcu *next,
- unsigned char flags);
+ unsigned char flags, const unsigned char *src);
void br_mdb_init(void);
void br_mdb_uninit(void);
void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port,
diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c
index 8bd5696..05e8946 100644
--- a/net/bridge/br_sysfs_if.c
+++ b/net/bridge/br_sysfs_if.c
@@ -188,6 +188,7 @@ static BRPORT_ATTR(multicast_router, S_IRUGO | S_IWUSR, show_multicast_router,
store_multicast_router);
BRPORT_ATTR_FLAG(multicast_fast_leave, BR_MULTICAST_FAST_LEAVE);
+BRPORT_ATTR_FLAG(multicast_to_unicast, BR_MULTICAST_TO_UNICAST);
#endif
static const struct brport_attribute *brport_attrs[] = {
@@ -214,6 +215,7 @@ static const struct brport_attribute *brport_attrs[] = {
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
&brport_attr_multicast_router,
&brport_attr_multicast_fast_leave,
+ &brport_attr_multicast_to_unicast,
#endif
&brport_attr_proxyarp,
&brport_attr_proxyarp_wifi,
--
2.1.4
^ permalink raw reply related
* Re: [PATCH v2 2/3] mwifiex: pcie: don't loop/retry interrupt status checks
From: Dmitry Torokhov @ 2017-01-17 20:44 UTC (permalink / raw)
To: Brian Norris
Cc: Amitkumar Karwar, Nishant Sarmukadam, linux-kernel, Kalle Valo,
linux-wireless, Cathy Luo
In-Reply-To: <20170117194822.GA29749@google.com>
On Tue, Jan 17, 2017 at 11:48:22AM -0800, Brian Norris wrote:
> On Sun, Jan 15, 2017 at 04:54:52PM -0800, Dmitry Torokhov wrote:
> > On Fri, Jan 13, 2017 at 03:35:37PM -0800, Brian Norris wrote:
> > > The following sequence occurs when using IEEE power-save on 8997:
> > > (a) driver sees SLEEP event
> > > (b) driver issues SLEEP CONFIRM
> > > (c) driver recevies CMD interrupt; within the interrupt processing loop,
> > > we do (d) and (e):
> > > (d) wait for FW sleep cookie (and often time out; it takes a while), FW
> > > is putting card into low power mode
> > > (e) re-check PCIE_HOST_INT_STATUS register; quit loop with 0 value
> > >
> > > But at (e), no one actually signaled an interrupt (i.e., we didn't check
> > > adapter->int_status). And what's more, because the card is going to
> > > sleep, this register read appears to take a very long time in some cases
> > > -- 3 milliseconds in my case!
> > >
> > > Now, I propose that (e) is completely unnecessary. If there were any
> > > additional interrupts signaled after the start of this loop, then the
> > > interrupt handler would have set adapter->int_status to non-zero and
> > > queued more work for the main loop -- and we'd catch it on the next
> > > iteration of the main loop.
> > >
> > > So this patch drops all the looping/re-reading of PCIE_HOST_INT_STATUS,
> > > which avoids the problematic (and slow) register read in step (e).
> > >
> > > Incidentally, this is a very similar issue to the one fixed in commit
> > > ec815dd2a5f1 ("mwifiex: prevent register accesses after host is
> > > sleeping"), except that the register read is just very slow instead of
> > > fatal in this case.
> > >
> > > Tested on 8997 in both MSI and (though not technically supported at the
> > > moment) MSI-X mode.
> >
> > Well, that kills interrupt mitigation and with PCIE that might be
> > somewhat important (SDIO is too slow to be important I think) and might
> > cost you throughput.
>
> Hmm, well I don't see us disabling interrupts in here, at least for MSI
> mode, so it doesn't actually look like a mitigation mechanism. More like
> a redundancy. But I'm not an expert on MSI, and definitely not on
> network performance.
Well, right, maybe not mitigation, but at least you have a chance to
avoid scheduling latency at times.
>
> Also, FWIW, I did some fairly non-scientific tests of this on my
> systems, and I didn't see much difference. I can run better tests, and
> even collect data on how often we loop here vs. see new interrupts.
That would be great. Maybe packet aggregation takes care of interrupts
arriving "too closely" together most of the time, I dunno.
>
> > OTOH maybe Marvell should convert PICE to NAPI to make this more
> > obvious and probably more correct.
>
> From my brief reading, that sounds like a better way to make this
> configurable.
>
> So I'm not sure which way you'd suggest then; take a patch like this,
> which makes the driver more clear and less buggy? Or write some
> different patch that isolates just the power-save related condition, so
> we break out of this look [1]?
I think it really depends on the test results. If we do not see
degradation in both throughput and latency then I think we can take this
patch and then see if switching to NAPI would be the ultimate solution.
>
> I'm also interested in any opinions from the Marvell side -- potentially
> testing results, rationale behind this code structure, or even a better
> alternative patch.
>
> Brian
>
> [1] i.e., along the lines of commit ec815dd2a5f1 ("mwifiex: prevent
> register accesses after host is sleeping").
Thanks.
--
Dmitry
^ permalink raw reply
* [PATCH] brcmfmac: fix incorrect event channel deduction
From: gavinli @ 2017-01-17 22:29 UTC (permalink / raw)
To: arend.vanspriel, franky.lin, hante.meuleman, linux-wireless,
brcm80211-dev-list.pdl
Cc: Gavin Li
From: Gavin Li <git@thegavinli.com>
brcmf_sdio_fromevntchan() was being called on the the hardware header
rather than the software header, causing some frames to be
mischaracterized as on the event channel rather than the data channel.
This fixes the performance regression introduced in commit c56caa9d
where event processing is done separately.
Signed-off-by: Gavin Li <git@thegavinli.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index dfb0658713d9..d2219885071f 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -1661,7 +1661,7 @@ static u8 brcmf_sdio_rxglom(struct brcmf_sdio *bus, u8 rxseq)
pfirst->len, pfirst->next,
pfirst->prev);
skb_unlink(pfirst, &bus->glom);
- if (brcmf_sdio_fromevntchan(pfirst->data))
+ if (brcmf_sdio_fromevntchan(&dptr[SDPCM_HWHDR_LEN]))
brcmf_rx_event(bus->sdiodev->dev, pfirst);
else
brcmf_rx_frame(bus->sdiodev->dev, pfirst,
--
2.11.0
^ permalink raw reply related
* Re: [PATCH] brcmfmac: fix incorrect event channel deduction
From: Rafał Miłecki @ 2017-01-17 22:41 UTC (permalink / raw)
To: gavinli
Cc: Arend Van Spriel, Franky Lin, Hante Meuleman,
linux-wireless@vger.kernel.org,
open list:BROADCOM BRCM80211 IEEE802.11n WIRELESS DRIVER,
Gavin Li
In-Reply-To: <20170117222909.2880-1-gavinli@thegavinli.com>
On 17 January 2017 at 23:29, <gavinli@thegavinli.com> wrote:
> From: Gavin Li <git@thegavinli.com>
>
> brcmf_sdio_fromevntchan() was being called on the the hardware header
> rather than the software header, causing some frames to be
> mischaracterized as on the event channel rather than the data channel.
> This fixes the performance regression introduced in commit c56caa9d
> where event processing is done separately.
This should be:
in commit c56caa9db8ab ("brcmfmac: screening firmware event packet") where (...)
You should also use
Fixes: c56caa9db8ab ("brcmfmac: screening firmware event packet") where (...)
> Signed-off-by: Gavin Li <git@thegavinli.com>
Please add also:
Cc: stable@vger.kernel.org # 4.6+
^ permalink raw reply
* Re: [PATCH] brcmfmac: fix incorrect event channel deduction
From: Rafał Miłecki @ 2017-01-17 22:41 UTC (permalink / raw)
To: gavinli
Cc: Arend Van Spriel, Franky Lin, Hante Meuleman,
linux-wireless@vger.kernel.org,
open list:BROADCOM BRCM80211 IEEE802.11n WIRELESS DRIVER,
Gavin Li
In-Reply-To: <CACna6rymMzoYJHBYb3PQpyNomp-HixAFqvtafMw72dySk8MPLQ@mail.gmail.com>
On 17 January 2017 at 23:41, Rafa=C5=82 Mi=C5=82ecki <zajec5@gmail.com> wro=
te:
> On 17 January 2017 at 23:29, <gavinli@thegavinli.com> wrote:
>> From: Gavin Li <git@thegavinli.com>
>>
>> brcmf_sdio_fromevntchan() was being called on the the hardware header
>> rather than the software header, causing some frames to be
>> mischaracterized as on the event channel rather than the data channel.
>> This fixes the performance regression introduced in commit c56caa9d
>> where event processing is done separately.
>
> This should be:
> in commit c56caa9db8ab ("brcmfmac: screening firmware event packet") wher=
e (...)
>
> You should also use
> Fixes: c56caa9db8ab ("brcmfmac: screening firmware event packet") where (=
...)
Oops, copy & paste mistake. Just:
Fixes: c56caa9db8ab ("brcmfmac: screening firmware event packet")
--=20
Rafa=C5=82
^ permalink raw reply
* [PATCH] brcmfmac: use wiphy_read_of_freq_limits to respect limits from DT
From: Rafał Miłecki @ 2017-01-17 22:35 UTC (permalink / raw)
To: Kalle Valo
Cc: Arend van Spriel, Franky Lin, Hante Meuleman,
Pieter-Paul Giesberts, Franky Lin, linux-wireless,
brcm80211-dev-list.pdl, Rafał Miłecki
From: Rafał Miłecki <rafal@milecki.pl>
This new helper reads extra frequency limits specified in DT and
disables unavailable chanels. This is useful for devices (like home
routers) with chipsets limited e.g. by board design.
In order to respect info read from DT we simply need to check for
IEEE80211_CHAN_DISABLED bit when constructing channel info.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
This patch requires e691ac2f75b6 ("cfg80211: support ieee80211-freq-limit DT
property") that is currently in net-next.
Kalle: feel free to postpone this until merging net-next one day.
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index ec1171c..b96fc88 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -5886,6 +5886,9 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
continue;
}
+ if (channel->orig_flags & IEEE80211_CHAN_DISABLED)
+ continue;
+
/* assuming the chanspecs order is HT20,
* HT40 upper, HT40 lower, and VHT80.
*/
@@ -6477,6 +6480,9 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
wiphy->bands[NL80211_BAND_5GHZ] = band;
}
}
+
+ wiphy_read_of_freq_limits(wiphy);
+
return 0;
}
--
2.10.1
^ permalink raw reply related
* [PATCH] brcmfmac: fix incorrect event channel deduction
From: gavinli @ 2017-01-17 22:55 UTC (permalink / raw)
To: arend.vanspriel, franky.lin, hante.meuleman, linux-wireless,
brcm80211-dev-list.pdl
Cc: stable, Gavin Li
From: Gavin Li <git@thegavinli.com>
brcmf_sdio_fromevntchan() was being called on the the data frame
rather than the software header, causing some frames to be
mischaracterized as on the event channel rather than the data channel.
This fixes a major performance regression (due to dropped packets).
Fixes: c56caa9db8ab ("brcmfmac: screening firmware event packet")
Signed-off-by: Gavin Li <git@thegavinli.com>
Cc: <stable@vger.kernel.org> [4.6+]
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index dfb0658713d9..d2219885071f 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -1661,7 +1661,7 @@ static u8 brcmf_sdio_rxglom(struct brcmf_sdio *bus, u8 rxseq)
pfirst->len, pfirst->next,
pfirst->prev);
skb_unlink(pfirst, &bus->glom);
- if (brcmf_sdio_fromevntchan(pfirst->data))
+ if (brcmf_sdio_fromevntchan(&dptr[SDPCM_HWHDR_LEN]))
brcmf_rx_event(bus->sdiodev->dev, pfirst);
else
brcmf_rx_frame(bus->sdiodev->dev, pfirst,
--
2.11.0
^ permalink raw reply related
* [PATCH] brcmfmac: fix incorrect event channel deduction
From: gavinli @ 2017-01-17 22:50 UTC (permalink / raw)
To: arend.vanspriel, franky.lin, hante.meuleman, linux-wireless,
brcm80211-dev-list.pdl
Cc: stable, Gavin Li
From: Gavin Li <git@thegavinli.com>
brcmf_sdio_fromevntchan() was being called on the the data frame
rather than the software header, causing some frames to be
mischaracterized as on the event channel rather than the data channel.
This fixes a major performance regression (due to dropped packets).
Fixes: c56caa9db8ab ("brcmfmac: screening firmware event packet")
Signed-off-by: Gavin Li <git@thegavinli.com>
Cc: <stable@vger.kernel.org> [4.6+]
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index dfb0658713d9..d2219885071f 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -1661,7 +1661,7 @@ static u8 brcmf_sdio_rxglom(struct brcmf_sdio *bus, u8 rxseq)
pfirst->len, pfirst->next,
pfirst->prev);
skb_unlink(pfirst, &bus->glom);
- if (brcmf_sdio_fromevntchan(pfirst->data))
+ if (brcmf_sdio_fromevntchan(&dptr[SDPCM_HWHDR_LEN]))
brcmf_rx_event(bus->sdiodev->dev, pfirst);
else
brcmf_rx_frame(bus->sdiodev->dev, pfirst,
--
2.11.0
^ permalink raw reply related
* [PATCH] brcmfmac: fix incorrect event channel deduction
From: gavinli @ 2017-01-17 23:15 UTC (permalink / raw)
To: arend.vanspriel, franky.lin, hante.meuleman, linux-wireless,
brcm80211-dev-list.pdl
Cc: stable, Gavin Li
From: Gavin Li <git@thegavinli.com>
brcmf_sdio_fromevntchan() was being called on the the data frame
rather than the software header, causing some frames to be
mischaracterized as on the event channel rather than the data channel.
This fixes a major performance regression (due to dropped packets).
Fixes: c56caa9db8ab ("brcmfmac: screening firmware event packet")
Signed-off-by: Gavin Li <git@thegavinli.com>
Cc: <stable@vger.kernel.org> [4.7+]
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index dfb0658713d9..d2219885071f 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -1661,7 +1661,7 @@ static u8 brcmf_sdio_rxglom(struct brcmf_sdio *bus, u8 rxseq)
pfirst->len, pfirst->next,
pfirst->prev);
skb_unlink(pfirst, &bus->glom);
- if (brcmf_sdio_fromevntchan(pfirst->data))
+ if (brcmf_sdio_fromevntchan(&dptr[SDPCM_HWHDR_LEN]))
brcmf_rx_event(bus->sdiodev->dev, pfirst);
else
brcmf_rx_frame(bus->sdiodev->dev, pfirst,
--
2.11.0
^ permalink raw reply related
* Re: [PATCH] brcmfmac: fix incorrect event channel deduction
From: Rafał Miłecki @ 2017-01-17 23:09 UTC (permalink / raw)
To: gavinli
Cc: Arend Van Spriel, Franky Lin, Hante Meuleman,
linux-wireless@vger.kernel.org,
open list:BROADCOM BRCM80211 IEEE802.11n WIRELESS DRIVER, Stable,
Gavin Li
In-Reply-To: <20170117225545.6706-1-gavinli@thegavinli.com>
On 17 January 2017 at 23:55, <gavinli@thegavinli.com> wrote:
> From: Gavin Li <git@thegavinli.com>
>
> brcmf_sdio_fromevntchan() was being called on the the data frame
> rather than the software header, causing some frames to be
> mischaracterized as on the event channel rather than the data channel.
>
> This fixes a major performance regression (due to dropped packets).
>
> Fixes: c56caa9db8ab ("brcmfmac: screening firmware event packet")
> Signed-off-by: Gavin Li <git@thegavinli.com>
> Cc: <stable@vger.kernel.org> [4.6+]
Oh, that was supposed to be 4.7+, I gave you a wrong hint, sorry!
You may send V3, or maybe ask Kalle to fix it by hand when applying the pat=
ch.
--=20
Rafa=C5=82
^ permalink raw reply
* [PATCH v3] brcmfmac: fix incorrect event channel deduction
From: gavinli @ 2017-01-17 23:24 UTC (permalink / raw)
To: arend.vanspriel, franky.lin, hante.meuleman, linux-wireless,
brcm80211-dev-list.pdl
Cc: stable, Gavin Li
From: Gavin Li <git@thegavinli.com>
brcmf_sdio_fromevntchan() was being called on the the data frame
rather than the software header, causing some frames to be
mischaracterized as on the event channel rather than the data channel.
This fixes a major performance regression (due to dropped packets).
Fixes: c56caa9db8ab ("brcmfmac: screening firmware event packet")
Signed-off-by: Gavin Li <git@thegavinli.com>
Cc: <stable@vger.kernel.org> [4.7+]
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index dfb0658713d9..d2219885071f 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -1661,7 +1661,7 @@ static u8 brcmf_sdio_rxglom(struct brcmf_sdio *bus, u8 rxseq)
pfirst->len, pfirst->next,
pfirst->prev);
skb_unlink(pfirst, &bus->glom);
- if (brcmf_sdio_fromevntchan(pfirst->data))
+ if (brcmf_sdio_fromevntchan(&dptr[SDPCM_HWHDR_LEN]))
brcmf_rx_event(bus->sdiodev->dev, pfirst);
else
brcmf_rx_frame(bus->sdiodev->dev, pfirst,
--
2.11.0
^ permalink raw reply related
* iwlwifi: fix kernel crash when unregistering thermal zone
From: Jens Axboe @ 2017-01-17 22:22 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless
A recent firmware change seems to have enabled thermal zones on the
iwlwifi driver. Unfortunately, my device fails when registering the
thermal zone. This doesn't stop the driver from attempting to unregister
the thermal zone at unload time, triggering a NULL pointer deference in
strlen() off the thermal_zone_device_unregister() path.
Don't unregister if name is NULL, for that case we failed registering.
Do the same for the cooling zone.
Signed-off-by: Jens Axboe <axboe@fb.com>
---
Would be great if this could go into the current series, as sometimes I
have to reload the driver. Right now I can't, since it crashes...
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
index 63a051be832e..bec7d9c46087 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
@@ -843,8 +843,10 @@ static void iwl_mvm_thermal_zone_unregister(struct iwl_mvm *mvm)
return;
IWL_DEBUG_TEMP(mvm, "Thermal zone device unregister\n");
- thermal_zone_device_unregister(mvm->tz_device.tzone);
- mvm->tz_device.tzone = NULL;
+ if (mvm->tz_device.tzone) {
+ thermal_zone_device_unregister(mvm->tz_device.tzone);
+ mvm->tz_device.tzone = NULL;
+ }
}
static void iwl_mvm_cooling_device_unregister(struct iwl_mvm *mvm)
@@ -853,8 +855,10 @@ static void iwl_mvm_cooling_device_unregister(struct iwl_mvm *mvm)
return;
IWL_DEBUG_TEMP(mvm, "Cooling device unregister\n");
- thermal_cooling_device_unregister(mvm->cooling_dev.cdev);
- mvm->cooling_dev.cdev = NULL;
+ if (mvm->cooling_dev.cdev) {
+ thermal_cooling_device_unregister(mvm->cooling_dev.cdev);
+ mvm->cooling_dev.cdev = NULL;
+ }
}
#endif /* CONFIG_THERMAL */
^ permalink raw reply related
* [PATCH 0/5] Update USB IDs and email adress
From: Jes.Sorensen @ 2017-01-17 23:18 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless
From: Jes Sorensen <Jes.Sorensen@gmail.com>
Hi,
This patchset adds some additional USB IDs for rtl8192eu devices, as
well as updates the email address and the copyright.
I've been preoccupied with some other stuff the last little while, so
I am a little out of touch with whether or not the patch window is
open at the moment. Please yell at me if you want me to resubmit these later.
Cheers,
Jes
Axel Köllhofer (2):
rtl8xxxu: Add USB ID for D-Link DWA-131 rev E1 (rtl8192eu)
rtl8xxxu: Add additional USB IDs for rtl8192eu devices
Jes Sorensen (3):
rtl8xxxu: Mark 8192eu device 0x0bda:0x818b as tested
rtl8xxxu: Add another 8192eu device to the USB list
rtl8xxxu: Update author/maintainer contact info
MAINTAINERS | 2 +-
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 2 +-
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192c.c | 2 +-
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c | 2 +-
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723a.c | 2 +-
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c | 2 +-
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 18 ++++++++++++++++--
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h | 2 +-
8 files changed, 23 insertions(+), 9 deletions(-)
--
2.7.4
^ permalink raw reply
* [PATCH 4/5] rtl8xxxu: Add additional USB IDs for rtl8192eu devices
From: Jes.Sorensen @ 2017-01-17 23:18 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless
In-Reply-To: <20170117231856.5075-1-Jes.Sorensen@gmail.com>
From: Axel Köllhofer <AxelKoellhofer@web.de>
These IDs originate from the vendor driver
Signed-off-by: Axel Köllhofer <AxelKoellhofer@web.de>
Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
---
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
index a8386f4..3585a04 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
@@ -6354,6 +6354,13 @@ static struct usb_device_id dev_table[] = {
.driver_info = (unsigned long)&rtl8192cu_fops},
{USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0x7822, 0xff, 0xff, 0xff),
.driver_info = (unsigned long)&rtl8192cu_fops},
+/* found in rtl8192eu vendor driver */
+{USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0107, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192eu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x2019, 0xab33, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192eu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x818c, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192eu_fops},
#endif
{ }
};
--
2.7.4
^ permalink raw reply related
* [PATCH 2/5] rtl8xxxu: Add another 8192eu device to the USB list
From: Jes.Sorensen @ 2017-01-17 23:18 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless
In-Reply-To: <20170117231856.5075-1-Jes.Sorensen@gmail.com>
From: Jes Sorensen <Jes.Sorensen@redhat.com>
TP-Link TL-WN822N v4 (2357:0108)
Reported-by: Gregory Auzanneau <linux@reolight.net>
Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
---
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
index 99cfd2b..016ea24 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
@@ -6197,6 +6197,9 @@ static struct usb_device_id dev_table[] = {
.driver_info = (unsigned long)&rtl8723au_fops},
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x818b, 0xff, 0xff, 0xff),
.driver_info = (unsigned long)&rtl8192eu_fops},
+/* TP-Link TL-WN822N v4 */
+{USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0108, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192eu_fops},
/* Tested by Myckel Habets */
{USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0109, 0xff, 0xff, 0xff),
.driver_info = (unsigned long)&rtl8192eu_fops},
--
2.7.4
^ permalink raw reply related
* [PATCH 3/5] rtl8xxxu: Add USB ID for D-Link DWA-131 rev E1 (rtl8192eu)
From: Jes.Sorensen @ 2017-01-17 23:18 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless
In-Reply-To: <20170117231856.5075-1-Jes.Sorensen@gmail.com>
From: Axel Köllhofer <AxelKoellhofer@web.de>
This was tested by David Patiño.
Reported-by: David Patiño <davidpatino82@gmail.com>
Signed-off-by: Axel Köllhofer <AxelKoellhofer@web.de>
Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
---
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
index 016ea24..a8386f4 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
@@ -6200,6 +6200,9 @@ static struct usb_device_id dev_table[] = {
/* TP-Link TL-WN822N v4 */
{USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0108, 0xff, 0xff, 0xff),
.driver_info = (unsigned long)&rtl8192eu_fops},
+/* D-Link DWA-131 rev E1, tested by David Patiño */
+{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3319, 0xff, 0xff, 0xff),
+ .driver_info = (unsigned long)&rtl8192eu_fops},
/* Tested by Myckel Habets */
{USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0109, 0xff, 0xff, 0xff),
.driver_info = (unsigned long)&rtl8192eu_fops},
--
2.7.4
^ permalink raw reply related
* [PATCH 5/5] rtl8xxxu: Update author/maintainer contact info
From: Jes.Sorensen @ 2017-01-17 23:18 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless
In-Reply-To: <20170117231856.5075-1-Jes.Sorensen@gmail.com>
From: Jes Sorensen <Jes.Sorensen@redhat.com>
Update copyright year and email address.
Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
---
MAINTAINERS | 2 +-
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 2 +-
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192c.c | 2 +-
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c | 2 +-
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723a.c | 2 +-
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c | 2 +-
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 4 ++--
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h | 2 +-
8 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index c8df0e1..0b5c80e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10584,7 +10584,7 @@ F: drivers/net/wireless/realtek/rtlwifi/
F: drivers/net/wireless/realtek/rtlwifi/rtl8192ce/
RTL8XXXU WIRELESS DRIVER (rtl8xxxu)
-M: Jes Sorensen <Jes.Sorensen@redhat.com>
+M: Jes Sorensen <Jes.Sorensen@gmail.com>
L: linux-wireless@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jes/linux.git rtl8xxxu-devel
S: Maintained
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
index df551b2..95e3993 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014 - 2016 Jes Sorensen <Jes.Sorensen@redhat.com>
+ * Copyright (c) 2014 - 2017 Jes Sorensen <Jes.Sorensen@gmail.com>
*
* 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
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192c.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192c.c
index f9e2050..a41a296 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192c.c
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192c.c
@@ -1,7 +1,7 @@
/*
* RTL8XXXU mac80211 USB driver - 8188c/8188r/8192c specific subdriver
*
- * Copyright (c) 2014 - 2016 Jes Sorensen <Jes.Sorensen@redhat.com>
+ * Copyright (c) 2014 - 2017 Jes Sorensen <Jes.Sorensen@gmail.com>
*
* Portions, notably calibration code:
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c
index a1178c5..80fee69 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c
@@ -1,7 +1,7 @@
/*
* RTL8XXXU mac80211 USB driver - 8192e specific subdriver
*
- * Copyright (c) 2014 - 2016 Jes Sorensen <Jes.Sorensen@redhat.com>
+ * Copyright (c) 2014 - 2017 Jes Sorensen <Jes.Sorensen@gmail.com>
*
* Portions, notably calibration code:
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723a.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723a.c
index aef3730..1746311 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723a.c
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723a.c
@@ -1,7 +1,7 @@
/*
* RTL8XXXU mac80211 USB driver - 8723a specific subdriver
*
- * Copyright (c) 2014 - 2016 Jes Sorensen <Jes.Sorensen@redhat.com>
+ * Copyright (c) 2014 - 2017 Jes Sorensen <Jes.Sorensen@gmail.com>
*
* Portions, notably calibration code:
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c
index 02b8ddd..c4b86a8 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c
@@ -1,7 +1,7 @@
/*
* RTL8XXXU mac80211 USB driver - 8723b specific subdriver
*
- * Copyright (c) 2014 - 2016 Jes Sorensen <Jes.Sorensen@redhat.com>
+ * Copyright (c) 2014 - 2017 Jes Sorensen <Jes.Sorensen@gmail.com>
*
* Portions, notably calibration code:
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
index 3585a04..e544dd1 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
@@ -1,7 +1,7 @@
/*
* RTL8XXXU mac80211 USB driver
*
- * Copyright (c) 2014 - 2016 Jes Sorensen <Jes.Sorensen@redhat.com>
+ * Copyright (c) 2014 - 2017 Jes Sorensen <Jes.Sorensen@gmail.com>
*
* Portions, notably calibration code:
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
@@ -48,7 +48,7 @@ static bool rtl8xxxu_dma_aggregation;
static int rtl8xxxu_dma_agg_timeout = -1;
static int rtl8xxxu_dma_agg_pages = -1;
-MODULE_AUTHOR("Jes Sorensen <Jes.Sorensen@redhat.com>");
+MODULE_AUTHOR("Jes Sorensen <Jes.Sorensen@gmail.com>");
MODULE_DESCRIPTION("RTL8XXXu USB mac80211 Wireless LAN Driver");
MODULE_LICENSE("GPL");
MODULE_FIRMWARE("rtlwifi/rtl8723aufw_A.bin");
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h
index 315ccfb..3d3e2e1 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014 - 2016 Jes Sorensen <Jes.Sorensen@redhat.com>
+ * Copyright (c) 2014 - 2017 Jes Sorensen <Jes.Sorensen@gmail.com>
*
* 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
--
2.7.4
^ permalink raw reply related
* [PATCH 1/5] rtl8xxxu: Mark 8192eu device 0x0bda:0x818b as tested
From: Jes.Sorensen @ 2017-01-17 23:18 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless
In-Reply-To: <20170117231856.5075-1-Jes.Sorensen@gmail.com>
From: Jes Sorensen <Jes.Sorensen@redhat.com>
Device reported as working fine, so tell the driver not to warn about
it being untested.
Reported-by: Aex Aey <aexaey@gmail.com>
Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
---
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
index 3a86675..99cfd2b 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
@@ -6000,6 +6000,7 @@ static int rtl8xxxu_probe(struct usb_interface *interface,
case 0x8176:
case 0x8178:
case 0x817f:
+ case 0x818b:
untested = 0;
break;
}
--
2.7.4
^ permalink raw reply related
* Clarifying rtl8188ee's channel wifi changing code
From: Farhan Khan @ 2017-01-18 5:40 UTC (permalink / raw)
To: linux-wireless
Hi all,
I am having a bit of trouble understanding the rtl8188ee source,
specifically how its switch_channel function (rtl88e_phy_sw_chnl) works. I
gather that this function calls rtl88ee_phy_sw_chnl_callback, which in turn
calls _rtl88_phy_sw_chnl_step_by_step (
https://github.com/torvalds/linux/blob/master/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/phy.c#L1253
).
This is where I get lost. Where is the 'channel' variable used, other than
to change the TX power? I presume it has something to do with case
CMDID_RF_WRITEREG, but I am not certain.
Please explain what is going on. Thank you!
^ permalink raw reply
* Re: [PATCH v2 2/3] mwifiex: pcie: don't loop/retry interrupt status checks
From: Brian Norris @ 2017-01-18 2:09 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Amitkumar Karwar, Nishant Sarmukadam, linux-kernel, Kalle Valo,
linux-wireless, Cathy Luo
In-Reply-To: <20170117204455.GA6888@dtor-ws>
[-- Attachment #1: Type: text/plain, Size: 2653 bytes --]
On Tue, Jan 17, 2017 at 12:44:55PM -0800, Dmitry Torokhov wrote:
> On Tue, Jan 17, 2017 at 11:48:22AM -0800, Brian Norris wrote:
> > Also, FWIW, I did some fairly non-scientific tests of this on my
> > systems, and I didn't see much difference. I can run better tests, and
> > even collect data on how often we loop here vs. see new interrupts.
>
> That would be great. Maybe packet aggregation takes care of interrupts
> arriving "too closely" together most of the time, I dunno.
OK, so I did some basic accounting of how many times this while loop
runs in a row. I don't know if they're highly illuminating, but here
goes. They're listed as a histogram, where the first column is number of
samples that exhibited the behavior and second column is number of times
going through the loop before exiting (i.e., seeing no more INT_STATUS):
Idle (just scanning for networks occasionally, and loading a web page or
two) for a minute or two:
1
265 1
2 2
Downloading a Chrome .deb package via wget, in a loop:
857 0
36406 1
32386 2
2230 3
153 4
11 5
Running a perf client test (i.e., TX traffic) in a loop:
1694 0
247897 1
25530 2
441 3
18 4
So it seems like in some cases, it's at least *possible* to have a little bit
of potential savings on 10-50% of interrupts when under load. (i.e., see
that ~50% of interrupt checks take 2, 3, 4, or 5 loops in the second
example.)
Now, I also did some perf numbers with iperf between a Raspberry Pi iperf
server and an ARM64 system running mwifiex. On the whole, the TX side was
probably bottlenecked by the RPi, but the RX side was pretty good.
I'll attach full numbers, but the percentage delta is as follows:
Mean Median
------ ------
% change, bi-direction (RX): -0.3 -4.5
% change, bi-direction (TX): 1.034 4.45
% change, TX only: 12.96 13.35
% change, RX only: -6.5 -3
I'm not sure I have a good explanation for the gain in TX performance.
Perhaps partly the reduction in complexity (e.g., unnecessary register
reads). Perhaps also because I had IEEE power-save enabled, so without
this patch, performance could (theoretically) be harmed by the issue
mentioned in the commit description (i.e., occasional slow PCIe reads)
-- though I guess we probably don't enter power-save often during iperf
tests.
So, there could definitely be some methodology mistakes or other
variables involved, but these don't seem to show any particularly bad
performance loss, and if we did, we might consider other approaches like
NAPI for tuning them.
Brian
[-- Attachment #2: summary.csv --]
[-- Type: text/csv, Size: 1140 bytes --]
,Mbit/s,,,,,,,,,,Min,Max,Mean,Median,Stddev
Before: Bidirectional RX,193,163,198,147,194,195,129,167,198,174,129,198,175.8,183.5,24.142171494
Before: Bidirectional TX,15.2,21.4,15.8,26.2,13.8,12.6,22.9,14.3,14.7,35.1,12.6,35.1,19.2,15.5,7.1870253466
Before: TX only,60.6,52.4,70,66,60.9,64.9,58.3,59.8,53.3,58.3,52.4,70,60.45,60.2,5.4530827163
Before: RX only,151,186,209,201,180,208,210,189,176,196,151,210,190.6,192.5,18.476411388
After: Bidirectional RX,171,194,187,165,167,197,163,199,192,120,120,199,175.5,179,24.0381641007
After: Bidirectional TX,30.4,19,19.8,20.2,20.7,20.1,27.3,18.8,19.3,6.74,6.74,30.4,20.234,19.95,6.1485322548
After: TX only,73.9,78.1,73.3,73.2,74.5,82.1,73.8,69.6,68.7,66.9,66.9,82.1,73.41,73.55,4.4500811478
After: RX only,160,163,179,195,203,187,192,202,207,153,153,207,184.1,189.5,19.4676369621
,,,,,,,,,,,,,,,
Delta: Bidirectional RX,,,,,,,,,,,,,-0.3,-4.5,
Delta: Bidirectional TX,,,,,,,,,,,,,1.034,4.45,
Delta: TX only,,,,,,,,,,,,,12.96,13.35,
Delta: RX only,,,,,,,,,,,,,-6.5,-3,
,,,,,,,,,,,,,,,
,,,,,,,,,,,,,-0.17%,-2.45%,
,,,,,,,,,,,,,5.39%,28.71%,
,,,,,,,,,,,,,21.44%,22.18%,
,,,,,,,,,,,,,-3.41%,-1.56%,
^ permalink raw reply
* Re: Clarifying rtl8188ee's channel wifi changing code
From: Larry Finger @ 2017-01-18 3:02 UTC (permalink / raw)
To: Farhan Khan, linux-wireless
In-Reply-To: <20170118054001.GA88602@offmail.us>
On 01/17/2017 11:40 PM, Farhan Khan wrote:
> Hi all,
>
> I am having a bit of trouble understanding the rtl8188ee source,
> specifically how its switch_channel function (rtl88e_phy_sw_chnl) works. I
> gather that this function calls rtl88ee_phy_sw_chnl_callback, which in turn
> calls _rtl88_phy_sw_chnl_step_by_step (
> https://github.com/torvalds/linux/blob/master/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/phy.c#L1253
> ).
>
> This is where I get lost. Where is the 'channel' variable used, other than
> to change the TX power? I presume it has something to do with case
> CMDID_RF_WRITEREG, but I am not certain.
>
> Please explain what is going on. Thank you!
I have no idea where you are getting those routine names, but my source does not
have them, unless something has broken grep on my system.
Larry
^ permalink raw reply
* Re: [PATCH] brcmfmac: use wiphy_read_of_freq_limits to respect limits from DT
From: kbuild test robot @ 2017-01-18 4:55 UTC (permalink / raw)
To: Rafał Miłecki
Cc: kbuild-all, Kalle Valo, Arend van Spriel, Franky Lin,
Hante Meuleman, Pieter-Paul Giesberts, Franky Lin, linux-wireless,
brcm80211-dev-list.pdl, Rafał Miłecki
In-Reply-To: <20170117223550.12114-1-zajec5@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1567 bytes --]
Hi Rafał,
[auto build test ERROR on wireless-drivers-next/master]
[cannot apply to v4.10-rc4 next-20170117]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Rafa-Mi-ecki/brcmfmac-use-wiphy_read_of_freq_limits-to-respect-limits-from-DT/20170118-122222
base: https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git master
config: x86_64-randconfig-x013-201703 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
All errors (new ones prefixed by >>):
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c: In function 'brcmf_setup_wiphy':
>> drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c:6484:2: error: implicit declaration of function 'wiphy_read_of_freq_limits' [-Werror=implicit-function-declaration]
wiphy_read_of_freq_limits(wiphy);
^~~~~~~~~~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
vim +/wiphy_read_of_freq_limits +6484 drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
6478
6479 band->n_channels = ARRAY_SIZE(__wl_5ghz_channels);
6480 wiphy->bands[NL80211_BAND_5GHZ] = band;
6481 }
6482 }
6483
> 6484 wiphy_read_of_freq_limits(wiphy);
6485
6486 return 0;
6487 }
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 35205 bytes --]
^ permalink raw reply
* Re: [PATCH net-next v2] bridge: multicast to unicast
From: kbuild test robot @ 2017-01-18 5:59 UTC (permalink / raw)
To: Linus Lüssing
Cc: kbuild-all, netdev, David S . Miller, Stephen Hemminger,
Felix Fietkau, Nikolay Aleksandrov, bridge, linux-kernel,
linux-wireless, Linus Lüssing
In-Reply-To: <20170117195917.16209-1-linus.luessing@c0d3.blue>
[-- Attachment #1: Type: text/plain, Size: 3250 bytes --]
Hi Felix,
[auto build test WARNING on net-next/master]
url: https://github.com/0day-ci/linux/commits/Linus-L-ssing/bridge-multicast-to-unicast/20170118-120345
config: x86_64-rhel-7.2 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings
All warnings (new ones prefixed by >>):
net/bridge/br_forward.c: In function 'br_multicast_flood':
>> net/bridge/br_forward.c:261:27: warning: 'port' may be used uninitialized in this function [-Wmaybe-uninitialized]
struct net_bridge_port *port, *lport, *rport;
^~~~
vim +/port +261 net/bridge/br_forward.c
5cb5e947 Herbert Xu 2010-02-27 245 #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
5cb5e947 Herbert Xu 2010-02-27 246 /* called with rcu_read_lock */
37b090e6 Nikolay Aleksandrov 2016-07-14 247 void br_multicast_flood(struct net_bridge_mdb_entry *mdst,
b35c5f63 Nikolay Aleksandrov 2016-07-14 248 struct sk_buff *skb,
37b090e6 Nikolay Aleksandrov 2016-07-14 249 bool local_rcv, bool local_orig)
5cb5e947 Herbert Xu 2010-02-27 250 {
5cb5e947 Herbert Xu 2010-02-27 251 struct net_device *dev = BR_INPUT_SKB_CB(skb)->brdev;
1080ab95 Nikolay Aleksandrov 2016-06-28 252 u8 igmp_type = br_multicast_igmp_type(skb);
5cb5e947 Herbert Xu 2010-02-27 253 struct net_bridge *br = netdev_priv(dev);
afe0159d stephen hemminger 2010-04-27 254 struct net_bridge_port *prev = NULL;
5cb5e947 Herbert Xu 2010-02-27 255 struct net_bridge_port_group *p;
5cb5e947 Herbert Xu 2010-02-27 256 struct hlist_node *rp;
5cb5e947 Herbert Xu 2010-02-27 257
e8051688 Eric Dumazet 2010-11-15 258 rp = rcu_dereference(hlist_first_rcu(&br->router_list));
83f6a740 stephen hemminger 2010-04-27 259 p = mdst ? rcu_dereference(mdst->ports) : NULL;
5cb5e947 Herbert Xu 2010-02-27 260 while (p || rp) {
afe0159d stephen hemminger 2010-04-27 @261 struct net_bridge_port *port, *lport, *rport;
afe0159d stephen hemminger 2010-04-27 262
5cb5e947 Herbert Xu 2010-02-27 263 lport = p ? p->port : NULL;
5cb5e947 Herbert Xu 2010-02-27 264 rport = rp ? hlist_entry(rp, struct net_bridge_port, rlist) :
5cb5e947 Herbert Xu 2010-02-27 265 NULL;
5cb5e947 Herbert Xu 2010-02-27 266
507962cd Felix Fietkau 2017-01-17 267 if ((unsigned long)lport > (unsigned long)rport) {
507962cd Felix Fietkau 2017-01-17 268 if (p->flags & MDB_PG_FLAGS_MCAST_TO_UCAST) {
507962cd Felix Fietkau 2017-01-17 269 maybe_deliver_addr(lport, skb, p->eth_addr,
:::::: The code at line 261 was first introduced by commit
:::::: afe0159d935ab731c682e811356914bb2be9470c bridge: multicast_flood cleanup
:::::: TO: stephen hemminger <shemminger@vyatta.com>
:::::: CC: David S. Miller <davem@davemloft.net>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 38262 bytes --]
^ permalink raw reply
* Re: [PATCH v3 2/2] mmc: pwrseq: add support for Marvell SD8787 chip
From: Matt Ranostay @ 2017-01-18 7:50 UTC (permalink / raw)
To: Shawn Lin
Cc: linux-wireless, Linux Kernel, linux-mmc, devicetree,
Tony Lindgren, Ulf Hansson
In-Reply-To: <0a49ba8d-e749-8462-fa48-7d8a17cecc75@rock-chips.com>
On Sun, Jan 15, 2017 at 6:35 PM, Shawn Lin <shawn.lin@rock-chips.com> wrote:
> On 2017/1/16 5:41, Matt Ranostay wrote:
>>
>> On Thu, Jan 12, 2017 at 11:16 PM, Shawn Lin <shawn.lin@rock-chips.com>
>> wrote:
>>>
>>> On 2017/1/13 13:29, Matt Ranostay wrote:
>>>>
>>>>
>>>> Allow power sequencing for the Marvell SD8787 Wifi/BT chip.
>>>> This can be abstracted to other chipsets if needed in the future.
>>>>
>>>> Cc: Tony Lindgren <tony@atomide.com>
>>>> Cc: Ulf Hansson <ulf.hansson@linaro.org>
>>>> Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
>>>> ---
>>>> drivers/mmc/core/Kconfig | 10 ++++
>>>> drivers/mmc/core/Makefile | 1 +
>>>> drivers/mmc/core/pwrseq_sd8787.c | 117
>>>> +++++++++++++++++++++++++++++++++++++++
>>>> 3 files changed, 128 insertions(+)
>>>> create mode 100644 drivers/mmc/core/pwrseq_sd8787.c
>>>>
>>>> diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig
>>>> index cdfa8520a4b1..fc1ecdaaa9ca 100644
>>>> --- a/drivers/mmc/core/Kconfig
>>>> +++ b/drivers/mmc/core/Kconfig
>>>> @@ -12,6 +12,16 @@ config PWRSEQ_EMMC
>>>> This driver can also be built as a module. If so, the module
>>>> will be called pwrseq_emmc.
>>>>
>>>> +config PWRSEQ_SD8787
>>>> + tristate "HW reset support for SD8787 BT + Wifi module"
>>>> + depends on OF && (MWIFIEX || BT_MRVL_SDIO)
>>>> + help
>>>> + This selects hardware reset support for the SD8787 BT + Wifi
>>>> + module. By default this option is set to n.
>>>> +
>>>> + This driver can also be built as a module. If so, the module
>>>> + will be called pwrseq_sd8787.
>>>> +
>>>
>>>
>>>
>>> I don't like this way, as we have a chance to list lots
>>> configure options here. wifi A,B,C,D...Z, all of them need a
>>> new section here if needed?
>>>
>>> Instead, could you just extent pwrseq_simple.c and add you
>>> .compatible = "mmc-pwrseq-sd8787", "mmc-pwrseq-simple"?
>>
>>
>> You mean all the chipset pwrseqs linked into the pwrseq-simple module?
>
>
> What I mean was if you just extent the pwrseq-simple a bit, you could
> just add your chipset pwrseqs linked into the pwrseq-simple. But if you
> need a different *pattern* of pwrseqs, you should need a new name, for
> instance, pwrseq-sdio.c etc... But please don't use the name of
> sd8787? So if I use a wifi named ABC but using the same pwrseq pattenr,
> should I include your "mmc-pwrseq- sd8787" for that or I need a new
> mmc-pwrseq-ABC.c?
Ah so pwrseq-sdio.c seems reasonable and having chipsets functions
defined in a structure. That could be abstracted out for other
chipsets that could needed in the future.
- Matt
>
>
>>
>> Ulf your thoughts on this?
>>
>>>
>>>
>>>
>>>> config PWRSEQ_SIMPLE
>>>> tristate "Simple HW reset support for MMC"
>>>> default y
>>>> diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile
>>>> index b2a257dc644f..0f81464fa824 100644
>>>> --- a/drivers/mmc/core/Makefile
>>>> +++ b/drivers/mmc/core/Makefile
>>>> @@ -10,6 +10,7 @@ mmc_core-y := core.o bus.o host.o \
>>>> quirks.o slot-gpio.o
>>>> mmc_core-$(CONFIG_OF) += pwrseq.o
>>>> obj-$(CONFIG_PWRSEQ_SIMPLE) += pwrseq_simple.o
>>>> +obj-$(CONFIG_PWRSEQ_SD8787) += pwrseq_sd8787.o
>>>> obj-$(CONFIG_PWRSEQ_EMMC) += pwrseq_emmc.o
>>>> mmc_core-$(CONFIG_DEBUG_FS) += debugfs.o
>>>> obj-$(CONFIG_MMC_BLOCK) += mmc_block.o
>>>> diff --git a/drivers/mmc/core/pwrseq_sd8787.c
>>>> b/drivers/mmc/core/pwrseq_sd8787.c
>>>> new file mode 100644
>>>> index 000000000000..f4080fe6439e
>>>> --- /dev/null
>>>> +++ b/drivers/mmc/core/pwrseq_sd8787.c
>>>> @@ -0,0 +1,117 @@
>>>> +/*
>>>> + * pwrseq_sd8787.c - power sequence support for Marvell SD8787 BT +
>>>> Wifi
>>>> chip
>>>> + *
>>>> + * Copyright (C) 2016 Matt Ranostay <matt@ranostay.consulting>
>>>> + *
>>>> + * Based on the original work pwrseq_simple.c
>>>> + * Copyright (C) 2014 Linaro Ltd
>>>> + * Author: Ulf Hansson <ulf.hansson@linaro.org>
>>>> + *
>>>> + * This program is free software; you can redistribute it and/or modify
>>>> + * it under the terms of the GNU General Public License as published by
>>>> + * the Free Software Foundation; either version 2 of the License, or
>>>> + * (at your option) any later version.
>>>> + *
>>>> + * 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.
>>>> + *
>>>> + */
>>>> +
>>>> +#include <linux/delay.h>
>>>> +#include <linux/init.h>
>>>> +#include <linux/kernel.h>
>>>> +#include <linux/platform_device.h>
>>>> +#include <linux/module.h>
>>>> +#include <linux/slab.h>
>>>> +#include <linux/device.h>
>>>> +#include <linux/err.h>
>>>> +#include <linux/gpio/consumer.h>
>>>> +
>>>> +#include <linux/mmc/host.h>
>>>> +
>>>> +#include "pwrseq.h"
>>>> +
>>>> +struct mmc_pwrseq_sd8787 {
>>>> + struct mmc_pwrseq pwrseq;
>>>> + struct gpio_desc *reset_gpio;
>>>> + struct gpio_desc *pwrdn_gpio;
>>>> +};
>>>> +
>>>> +#define to_pwrseq_sd8787(p) container_of(p, struct mmc_pwrseq_sd8787,
>>>> pwrseq)
>>>> +
>>>> +static void mmc_pwrseq_sd8787_pre_power_on(struct mmc_host *host)
>>>> +{
>>>> + struct mmc_pwrseq_sd8787 *pwrseq =
>>>> to_pwrseq_sd8787(host->pwrseq);
>>>> +
>>>> + gpiod_set_value_cansleep(pwrseq->reset_gpio, 1);
>>>> +
>>>> + msleep(300);
>>>> + gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 1);
>>>> +}
>>>> +
>>>> +static void mmc_pwrseq_sd8787_power_off(struct mmc_host *host)
>>>> +{
>>>> + struct mmc_pwrseq_sd8787 *pwrseq =
>>>> to_pwrseq_sd8787(host->pwrseq);
>>>> +
>>>> + gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 0);
>>>> + gpiod_set_value_cansleep(pwrseq->reset_gpio, 0);
>>>> +}
>>>> +
>>>> +static const struct mmc_pwrseq_ops mmc_pwrseq_sd8787_ops = {
>>>> + .pre_power_on = mmc_pwrseq_sd8787_pre_power_on,
>>>> + .power_off = mmc_pwrseq_sd8787_power_off,
>>>> +};
>>>> +
>>>> +static const struct of_device_id mmc_pwrseq_sd8787_of_match[] = {
>>>> + { .compatible = "mmc-pwrseq-sd8787",},
>>>> + {/* sentinel */},
>>>> +};
>>>> +MODULE_DEVICE_TABLE(of, mmc_pwrseq_sd8787_of_match);
>>>> +
>>>> +static int mmc_pwrseq_sd8787_probe(struct platform_device *pdev)
>>>> +{
>>>> + struct mmc_pwrseq_sd8787 *pwrseq;
>>>> + struct device *dev = &pdev->dev;
>>>> +
>>>> + pwrseq = devm_kzalloc(dev, sizeof(*pwrseq), GFP_KERNEL);
>>>> + if (!pwrseq)
>>>> + return -ENOMEM;
>>>> +
>>>> + pwrseq->pwrdn_gpio = devm_gpiod_get(dev, "pwrdn",
>>>> GPIOD_OUT_LOW);
>>>> + if (IS_ERR(pwrseq->pwrdn_gpio))
>>>> + return PTR_ERR(pwrseq->pwrdn_gpio);
>>>> +
>>>> + pwrseq->reset_gpio = devm_gpiod_get(dev, "reset",
>>>> GPIOD_OUT_LOW);
>>>> + if (IS_ERR(pwrseq->reset_gpio))
>>>> + return PTR_ERR(pwrseq->reset_gpio);
>>>> +
>>>> + pwrseq->pwrseq.dev = dev;
>>>> + pwrseq->pwrseq.ops = &mmc_pwrseq_sd8787_ops;
>>>> + pwrseq->pwrseq.owner = THIS_MODULE;
>>>> + platform_set_drvdata(pdev, pwrseq);
>>>> +
>>>> + return mmc_pwrseq_register(&pwrseq->pwrseq);
>>>> +}
>>>> +
>>>> +static int mmc_pwrseq_sd8787_remove(struct platform_device *pdev)
>>>> +{
>>>> + struct mmc_pwrseq_sd8787 *pwrseq = platform_get_drvdata(pdev);
>>>> +
>>>> + mmc_pwrseq_unregister(&pwrseq->pwrseq);
>>>> +
>>>> + return 0;
>>>> +}
>>>> +
>>>> +static struct platform_driver mmc_pwrseq_sd8787_driver = {
>>>> + .probe = mmc_pwrseq_sd8787_probe,
>>>> + .remove = mmc_pwrseq_sd8787_remove,
>>>> + .driver = {
>>>> + .name = "pwrseq_sd8787",
>>>> + .of_match_table = mmc_pwrseq_sd8787_of_match,
>>>> + },
>>>> +};
>>>> +
>>>> +module_platform_driver(mmc_pwrseq_sd8787_driver);
>>>> +MODULE_LICENSE("GPL v2");
>>>>
>>>
>>>
>>> --
>>> Best Regards
>>> Shawn Lin
>>>
>>
>>
>>
>
>
> --
> Best Regards
> Shawn Lin
>
^ permalink raw reply
* Re: [PATCH] brcmfmac: use wiphy_read_of_freq_limits to respect limits from DT
From: Kalle Valo @ 2017-01-18 8:01 UTC (permalink / raw)
To: kbuild test robot
Cc: Rafał Miłecki, kbuild-all, Arend van Spriel, Franky Lin,
Hante Meuleman, Pieter-Paul Giesberts, Franky Lin, linux-wireless,
brcm80211-dev-list.pdl, Rafał Miłecki
In-Reply-To: <201701181250.KMcvYlf0%fengguang.wu@intel.com>
kbuild test robot <lkp@intel.com> writes:
> Hi Rafa=C5=82,
>
> [auto build test ERROR on wireless-drivers-next/master]
> [cannot apply to v4.10-rc4 next-20170117]
> [if your patch is applied to the wrong git tree, please drop us a note to=
help improve the system]
>
> url: https://github.com/0day-ci/linux/commits/Rafa-Mi-ecki/brcmfmac-us=
e-wiphy_read_of_freq_limits-to-respect-limits-from-DT/20170118-122222
> base: https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-dr=
ivers-next.git master
> config: x86_64-randconfig-x013-201703 (attached as .config)
> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
> reproduce:
> # save the attached .config to linux build tree
> make ARCH=3Dx86_64=20
>
> All errors (new ones prefixed by >>):
>
> drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c: In functi=
on 'brcmf_setup_wiphy':
>>> drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c:6484:2: err=
or: implicit declaration of function 'wiphy_read_of_freq_limits' [-Werror=
=3Dimplicit-function-declaration]
> wiphy_read_of_freq_limits(wiphy);
> ^~~~~~~~~~~~~~~~~~~~~~~~~
The compiler error is expected as this depends on a cfg80211 patch not
yet in wireless-drivers-next.
--=20
Kalle Valo
^ 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