* 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
* [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 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 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: Brian Norris @ 2017-01-17 19:48 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Amitkumar Karwar, Nishant Sarmukadam, linux-kernel, Kalle Valo,
linux-wireless, Cathy Luo
In-Reply-To: <20170116005452.GI23285@dtor-ws>
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.
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.
> 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'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").
^ permalink raw reply
* [PATCH 1/2] brcmfmac: rename brcmf_bus_start function to brcmf_attach_phase2
From: Rafał Miłecki @ 2017-01-17 19:23 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 change intends to make init/attach process easier to follow.
What driver were doing in brcmf_bus_start wasn't bus specific at all and
function brcmf_bus_stop wasn't undoing things done there. It seems
brcmf_detach was actually undoing things done in both: brcmf_attach and
brcmf_bus_start.
To me it makes more sense to call these two function in a similar way as
they both handle some part of attaching process. It also makes
brcmf_detach more meaningful.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
This patchset is based on top of
[PATCH 2/2] brcmfmac: move function declarations to proper headers
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | 2 +-
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 4 ++--
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h | 4 ++--
drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 6 +++---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 6 +++---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 6 +++---
6 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
index 3e15d64..6fb7d12 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
@@ -74,7 +74,7 @@ module_param_named(roamoff, brcmf_roamoff, int, S_IRUSR);
MODULE_PARM_DESC(roamoff, "Do not use internal roaming engine");
#ifdef DEBUG
-/* always succeed brcmf_bus_start() */
+/* always succeed brcmf_attach_phase2() */
static int brcmf_ignore_probe_fail;
module_param_named(ignore_probe_fail, brcmf_ignore_probe_fail, int, 0);
MODULE_PARM_DESC(ignore_probe_fail, "always succeed probe for debugging");
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
index 9e6f60a..adf8eb1 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
@@ -893,7 +893,7 @@ static int brcmf_inet6addr_changed(struct notifier_block *nb,
}
#endif
-int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings)
+int brcmf_attach_phase1(struct device *dev, struct brcmf_mp_device *settings)
{
struct brcmf_pub *drvr = NULL;
int ret = 0;
@@ -966,7 +966,7 @@ static int brcmf_revinfo_read(struct seq_file *s, void *data)
return 0;
}
-int brcmf_bus_start(struct device *dev)
+int brcmf_attach_phase2(struct device *dev)
{
int ret = -1;
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
index d92beca..df4189e 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
@@ -226,8 +226,8 @@ void brcmf_rx_event(struct device *dev, struct sk_buff *rxp);
void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success);
void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on);
/* Indication from bus module regarding presence/insertion of dongle. */
-int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings);
-int brcmf_bus_start(struct device *dev);
+int brcmf_attach_phase1(struct device *dev, struct brcmf_mp_device *settings);
+int brcmf_attach_phase2(struct device *dev);
void brcmf_bus_add_txhdrlen(struct device *dev, uint len);
/* Indication from bus module that dongle should be reset */
void brcmf_dev_reset(struct device *dev);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index 048027f..bbc3ded 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -1568,11 +1568,11 @@ static int brcmf_pcie_attach_bus(struct brcmf_pciedev_info *devinfo)
int ret;
/* Attach to the common driver interface */
- ret = brcmf_attach(&devinfo->pdev->dev, devinfo->settings);
+ ret = brcmf_attach_phase1(&devinfo->pdev->dev, devinfo->settings);
if (ret) {
- brcmf_err("brcmf_attach failed\n");
+ brcmf_err("brcmf_attach_phase1 failed\n");
} else {
- ret = brcmf_bus_start(&devinfo->pdev->dev);
+ ret = brcmf_attach_phase2(&devinfo->pdev->dev);
if (ret)
brcmf_err("dongle is not responding\n");
}
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index dfb0658..5307223 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -4065,7 +4065,7 @@ static void brcmf_sdio_firmware_callback(struct device *dev,
sdio_release_host(sdiodev->func[1]);
- err = brcmf_bus_start(dev);
+ err = brcmf_attach_phase2(dev);
if (err != 0) {
brcmf_err("dongle is not responding\n");
goto fail;
@@ -4150,9 +4150,9 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
bus->tx_hdrlen = SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN;
/* Attach to the common layer, reserve hdr space */
- ret = brcmf_attach(bus->sdiodev->dev, bus->sdiodev->settings);
+ ret = brcmf_attach_phase1(bus->sdiodev->dev, bus->sdiodev->settings);
if (ret != 0) {
- brcmf_err("brcmf_attach failed\n");
+ brcmf_err("brcmf_attach_phase1 failed\n");
goto fail;
}
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
index 2f978a3..e031fea 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
@@ -1138,9 +1138,9 @@ static int brcmf_usb_bus_setup(struct brcmf_usbdev_info *devinfo)
int ret;
/* Attach to the common driver interface */
- ret = brcmf_attach(devinfo->dev, devinfo->settings);
+ ret = brcmf_attach_phase1(devinfo->dev, devinfo->settings);
if (ret) {
- brcmf_err("brcmf_attach failed\n");
+ brcmf_err("brcmf_attach_phase1 failed\n");
return ret;
}
@@ -1148,7 +1148,7 @@ static int brcmf_usb_bus_setup(struct brcmf_usbdev_info *devinfo)
if (ret)
goto fail;
- ret = brcmf_bus_start(devinfo->dev);
+ ret = brcmf_attach_phase2(devinfo->dev);
if (ret)
goto fail;
--
2.10.1
^ permalink raw reply related
* [PATCH 2/2] brcmfmac: drop brcmf_bus_detach and inline its code
From: Rafał Miłecki @ 2017-01-17 19:23 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
In-Reply-To: <20170117192325.14528-1-zajec5@gmail.com>
From: Rafał Miłecki <rafal@milecki.pl>
Driver used to call brcmf_bus_detach only from one place and it already
contained a check for drvr not being NULL. We can get rid of this extra
function, call brcmf_bus_stop directly and simplify the code.
There also isn't brcmf_bus_attach function which one could expect so it
looks more consistent this way.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 12 +-----------
1 file changed, 1 insertion(+), 11 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
index adf8eb1..122c79d 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
@@ -1075,16 +1075,6 @@ void brcmf_bus_add_txhdrlen(struct device *dev, uint len)
}
}
-static void brcmf_bus_detach(struct brcmf_pub *drvr)
-{
- brcmf_dbg(TRACE, "Enter\n");
-
- if (drvr) {
- /* Stop the bus module */
- brcmf_bus_stop(drvr->bus_if);
- }
-}
-
void brcmf_dev_reset(struct device *dev)
{
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
@@ -1131,7 +1121,7 @@ void brcmf_detach(struct device *dev)
brcmf_fws_deinit(drvr);
- brcmf_bus_detach(drvr);
+ brcmf_bus_stop(drvr->bus_if);
brcmf_proto_detach(drvr);
--
2.10.1
^ permalink raw reply related
* [PATCH 2/2] brcmfmac: move function declarations to proper headers
From: Rafał Miłecki @ 2017-01-17 16:34 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
In-Reply-To: <20170117163419.1184-1-zajec5@gmail.com>
From: Rafał Miłecki <rafal@milecki.pl>
Function brcmf_c_set_joinpref_default is in common.c, so move it to the
related header. All other (touched) ones are in core.c so take them out
of the bus.h.
I just needed to include bus.h to have enum brcmf_bus_state defined.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
.../net/wireless/broadcom/brcm80211/brcmfmac/bus.h | 28 ----------------------
.../wireless/broadcom/brcm80211/brcmfmac/common.h | 2 ++
.../wireless/broadcom/brcm80211/brcmfmac/core.h | 21 +++++++++++++++-
3 files changed, 22 insertions(+), 29 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
index b5bb971..58a3de6 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
@@ -214,34 +214,6 @@ int brcmf_bus_get_memdump(struct brcmf_bus *bus, void *data, size_t len)
return bus->ops->get_memdump(bus->dev, data, len);
}
-/*
- * interface functions from common layer
- */
-
-/* Receive frame for delivery to OS. Callee disposes of rxp. */
-void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp, bool handle_event);
-/* Receive async event packet from firmware. Callee disposes of rxp. */
-void brcmf_rx_event(struct device *dev, struct sk_buff *rxp);
-
-/* Indication from bus module regarding presence/insertion of dongle. */
-int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings);
-/* Indication from bus module regarding removal/absence of dongle */
-void brcmf_detach(struct device *dev);
-/* Indication from bus module that dongle should be reset */
-void brcmf_dev_reset(struct device *dev);
-/* Indication from bus module to change flow-control state */
-void brcmf_txflowblock(struct device *dev, bool state);
-
-/* Notify the bus has transferred the tx packet to firmware */
-void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success);
-
-/* Configure the "global" bus state used by upper layers */
-void brcmf_bus_change_state(struct brcmf_bus *bus, enum brcmf_bus_state state);
-
-int brcmf_bus_start(struct device *dev);
-s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, u32 len);
-void brcmf_bus_add_txhdrlen(struct device *dev, uint len);
-
#ifdef CONFIG_BRCMFMAC_SDIO
void brcmf_sdio_exit(void);
void brcmf_sdio_register(void);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
index bd095ab..a62f8e7 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
@@ -65,6 +65,8 @@ struct brcmf_mp_device {
} bus;
};
+void brcmf_c_set_joinpref_default(struct brcmf_if *ifp);
+
struct brcmf_mp_device *brcmf_get_module_param(struct device *dev,
enum brcmf_bus_type bus_type,
u32 chip, u32 chiprev);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
index c94dcab..d92beca 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
@@ -22,6 +22,7 @@
#define BRCMFMAC_CORE_H
#include <net/cfg80211.h>
+#include "bus.h"
#include "fweh.h"
#define TOE_TX_CSUM_OL 0x00000001
@@ -213,10 +214,28 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx,
void brcmf_remove_interface(struct brcmf_if *ifp, bool rtnl_locked);
void brcmf_txflowblock_if(struct brcmf_if *ifp,
enum brcmf_netif_stop_reason reason, bool state);
+/* Indication from bus module to change flow-control state */
+void brcmf_txflowblock(struct device *dev, bool state);
void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success);
void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb);
+/* Receive frame for delivery to OS. Callee disposes of rxp. */
+void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp, bool handle_event);
+/* Receive async event packet from firmware. Callee disposes of rxp. */
+void brcmf_rx_event(struct device *dev, struct sk_buff *rxp);
+/* Notify the bus has transferred the tx packet to firmware */
+void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success);
void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on);
-void brcmf_c_set_joinpref_default(struct brcmf_if *ifp);
+/* Indication from bus module regarding presence/insertion of dongle. */
+int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings);
+int brcmf_bus_start(struct device *dev);
+void brcmf_bus_add_txhdrlen(struct device *dev, uint len);
+/* Indication from bus module that dongle should be reset */
+void brcmf_dev_reset(struct device *dev);
+/* Indication from bus module regarding removal/absence of dongle */
+void brcmf_detach(struct device *dev);
+s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, u32 len);
+/* Configure the "global" bus state used by upper layers */
+void brcmf_bus_change_state(struct brcmf_bus *bus, enum brcmf_bus_state state);
int __init brcmf_core_init(void);
void __exit brcmf_core_exit(void);
--
2.10.1
^ permalink raw reply related
* [PATCH 1/2] brcmfmac: drop unneeded function declarations from headers
From: Rafał Miłecki @ 2017-01-17 16:34 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>
Functions brcmf_c_prec_enq and brcmf_sdio_init don't exist so we
really don't need their declarations. Function brcmf_parse_tlvs is used
in cfg80211.c only so make it static and drop from header as well.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h | 4 ----
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 2 +-
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h | 2 --
3 files changed, 1 insertion(+), 7 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
index e21f760..b5bb971 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
@@ -218,9 +218,6 @@ int brcmf_bus_get_memdump(struct brcmf_bus *bus, void *data, size_t len)
* interface functions from common layer
*/
-bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, struct sk_buff *pkt,
- int prec);
-
/* Receive frame for delivery to OS. Callee disposes of rxp. */
void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp, bool handle_event);
/* Receive async event packet from firmware. Callee disposes of rxp. */
@@ -247,7 +244,6 @@ void brcmf_bus_add_txhdrlen(struct device *dev, uint len);
#ifdef CONFIG_BRCMFMAC_SDIO
void brcmf_sdio_exit(void);
-void brcmf_sdio_init(void);
void brcmf_sdio_register(void);
#endif
#ifdef CONFIG_BRCMFMAC_USB
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 729bf33..ec1171c 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -326,7 +326,7 @@ u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
* triples, returning a pointer to the substring whose first element
* matches tag
*/
-const struct brcmf_tlv *
+static const struct brcmf_tlv *
brcmf_parse_tlvs(const void *buf, int buflen, uint key)
{
const struct brcmf_tlv *elt = buf;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
index 0c9a708..8f19d95 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
@@ -396,8 +396,6 @@ void brcmf_free_vif(struct brcmf_cfg80211_vif *vif);
s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
const u8 *vndr_ie_buf, u32 vndr_ie_len);
s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif);
-const struct brcmf_tlv *
-brcmf_parse_tlvs(const void *buf, int buflen, uint key);
u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
struct ieee80211_channel *ch);
bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info *cfg,
--
2.10.1
^ permalink raw reply related
* [PATCH v2] ath10k: Search SMBIOS for OEM board file extension
From: Waldemar Rymarkiewicz @ 2017-01-17 15:03 UTC (permalink / raw)
To: kvalo, ath10k
Cc: bartosz.markowski, rwchang, alanliu, linux-wireless,
Waldemar Rymarkiewicz
Board Data File (BDF) is loaded upon driver boot-up procedure. The right
board data file is identified, among others, by device and sybsystem ids.
The problem, however, can occur when the (default) board data file cannot
fulfill with the vendor requirements and it is necessary to use a different
board data file.
To solve the issue QCA uses SMBIOS type 0xF8 to store Board Data File Name
Extension to specify the extension/variant name. The driver will take the
extension suffix into consideration and will load the right (non-default)
board data file if necessary.
If it is unnecessary to use extension board data file, please leave the
SMBIOS field blank and default configuration will be used.
Example:
If a default board data file for a specific board is identified by a string
"bus=pci,vendor=168c,device=003e,subsystem-vendor=1028,
subsystem-device=0310"
then the OEM specific data file, if used, could be identified by variant
suffix:
"bus=pci,vendor=168c,device=003e,subsystem-vendor=1028,
subsystem-device=0310,variant=DE_1AB"
Signed-off-by: Waldemar Rymarkiewicz <ext.waldemar.rymarkiewicz@tieto.com>
---
drivers/net/wireless/ath/ath10k/core.c | 84 ++++++++++++++++++++++++++++++++--
drivers/net/wireless/ath/ath10k/core.h | 19 ++++++++
2 files changed, 100 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 874c2a755c66..c2afcca6fd60 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -18,6 +18,8 @@
#include <linux/module.h>
#include <linux/firmware.h>
#include <linux/of.h>
+#include <linux/dmi.h>
+#include <linux/ctype.h>
#include <asm/byteorder.h>
#include "core.h"
@@ -707,6 +709,72 @@ static int ath10k_core_get_board_id_from_otp(struct ath10k *ar)
return 0;
}
+static void ath10k_core_check_bdfext(const struct dmi_header *hdr, void *data)
+{
+ struct ath10k *ar = data;
+ const char *bdf_ext;
+ const char *magic = ATH10K_SMBIOS_BDF_EXT_MAGIC;
+ u8 bdf_enabled;
+ int i;
+
+ if (hdr->type != ATH10K_SMBIOS_BDF_EXT_TYPE)
+ return;
+
+ if (hdr->length != ATH10K_SMBIOS_BDF_EXT_LENGTH) {
+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
+ "wrong smbios bdf ext type length (%d).\n",
+ hdr->length);
+ return;
+ }
+
+ bdf_enabled = *((u8 *)hdr + ATH10K_SMBIOS_BDF_EXT_OFFSET);
+ if (!bdf_enabled) {
+ ath10k_dbg(ar, ATH10K_DBG_BOOT, "bdf variant name not found.\n");
+ return;
+ }
+
+ /* Only one string exists (per spec) */
+ bdf_ext = (char *)hdr + hdr->length;
+
+ if (memcmp(bdf_ext, magic, strlen(magic)) != 0) {
+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
+ "bdf variant magic does not match.\n");
+ return;
+ }
+
+ for (i = 0; i < strlen(bdf_ext); i++) {
+ if (!isascii(bdf_ext[i]) || !isprint(bdf_ext[i])) {
+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
+ "bdf variant name contains non ascii chars.\n");
+ return;
+ }
+ }
+
+ /* Copy extension name without magic suffix */
+ if (strscpy(ar->id.bdf_ext, bdf_ext + strlen(magic),
+ sizeof(ar->id.bdf_ext)) < 0) {
+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
+ "bdf variant string is longer than the buffer can accommodate (variant: %s)\n",
+ bdf_ext);
+ return;
+ }
+
+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
+ "found and validated bdf variant smbios_type 0x%x bdf %s\n",
+ ATH10K_SMBIOS_BDF_EXT_TYPE, bdf_ext);
+}
+
+static int ath10k_core_check_smbios(struct ath10k *ar)
+{
+ ar->id.bdf_ext[0] = '\0';
+ dmi_walk(ath10k_core_check_bdfext, ar);
+
+ if (ar->id.bdf_ext[0] == '\0')
+ return -ENODATA;
+
+ return 0;
+}
+
static int ath10k_download_and_run_otp(struct ath10k *ar)
{
u32 result, address = ar->hw_params.patch_load_addr;
@@ -1053,6 +1121,9 @@ static int ath10k_core_fetch_board_data_api_n(struct ath10k *ar,
static int ath10k_core_create_board_name(struct ath10k *ar, char *name,
size_t name_len)
{
+ /* strlen(',variant=') + strlen(ar->id.bdf_ext) */
+ char variant[9 + ATH10K_SMBIOS_BDF_EXT_STR_LENGTH];
+
if (ar->id.bmi_ids_valid) {
scnprintf(name, name_len,
"bus=%s,bmi-chip-id=%d,bmi-board-id=%d",
@@ -1062,12 +1133,15 @@ static int ath10k_core_create_board_name(struct ath10k *ar, char *name,
goto out;
}
+ if (ar->id.bdf_ext[0] != '\0')
+ scnprintf(variant, sizeof(variant), ",variant=%s",
+ ar->id.bdf_ext);
+
scnprintf(name, name_len,
- "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x",
+ "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x%s",
ath10k_bus_str(ar->hif.bus),
ar->id.vendor, ar->id.device,
- ar->id.subsystem_vendor, ar->id.subsystem_device);
-
+ ar->id.subsystem_vendor, ar->id.subsystem_device, variant);
out:
ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot using board name '%s'\n", name);
@@ -2128,6 +2202,10 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
goto err_free_firmware_files;
}
+ ret = ath10k_core_check_smbios(ar);
+ if (ret)
+ ath10k_dbg(ar, ATH10K_DBG_BOOT, "bdf variant name not set.\n");
+
ret = ath10k_core_fetch_board_file(ar);
if (ret) {
ath10k_err(ar, "failed to fetch board file: %d\n", ret);
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index c7664d6569fa..c7a289a4819d 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -69,6 +69,23 @@
#define ATH10K_NAPI_BUDGET 64
#define ATH10K_NAPI_QUOTA_LIMIT 60
+/* SMBIOS type containing Board Data File Name Extension */
+#define ATH10K_SMBIOS_BDF_EXT_TYPE 0xF8
+
+/* SMBIOS type structure length (excluding strings-set) */
+#define ATH10K_SMBIOS_BDF_EXT_LENGTH 0x9
+
+/* Offset pointing to Board Data File Name Extension */
+#define ATH10K_SMBIOS_BDF_EXT_OFFSET 0x8
+
+/* Board Data File Name Extension string length.
+ * String format: BDF_<Customer ID>_<Extension>\0
+ */
+#define ATH10K_SMBIOS_BDF_EXT_STR_LENGTH 0x20
+
+/* The magic used by QCA spec */
+#define ATH10K_SMBIOS_BDF_EXT_MAGIC "BDF_"
+
struct ath10k;
enum ath10k_bus {
@@ -781,6 +798,8 @@ struct ath10k {
bool bmi_ids_valid;
u8 bmi_board_id;
u8 bmi_chip_id;
+
+ char bdf_ext[ATH10K_SMBIOS_BDF_EXT_STR_LENGTH];
} id;
int fw_api;
--
2.11.0
^ permalink raw reply related
* Re: [4.10, fix, V2] Revert "bcma: init serial console directly from ChipCommon code"
From: Kalle Valo @ 2017-01-17 12:24 UTC (permalink / raw)
To: Rafał Miłecki
Cc: linux-wireless, Felix Fietkau, Rafał Miłecki
In-Reply-To: <20170113112335.23730-1-zajec5@gmail.com>
Rafał Miłecki wrote:
> From: Rafał Miłecki <rafal@milecki.pl>
>
> This reverts commit 4c81acab3816 ("bcma: init serial console directly
> from ChipCommon code") as it broke IRQ assignment. Getting IRQ with
> bcma_core_irq helper on SoC requires MIPS core to be set. It happens
> *after* ChipCommon initialization so we can't do this so early.
>
> This fixes a user reported regression. It wasn't critical as serial was
> still somehow working but lack of IRQs was making in unreliable.
>
> Fixes: 4c81acab3816 ("bcma: init serial console directly from ChipCommon code")
> Reported-by: Felix Fietkau <nbd@nbd.name>
> Cc: stable@vger.kernel.org # 4.6+
> Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Patch applied to wireless-drivers.git, thanks.
7195439d1d71 Revert "bcma: init serial console directly from ChipCommon code"
--
https://patchwork.kernel.org/patch/9515267/
Documentation about submitting wireless patches and checking status
from patchwork:
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
^ permalink raw reply
* Re: rtlwifi: rtl8192de: Remove a pointless goto
From: Kalle Valo @ 2017-01-17 12:13 UTC (permalink / raw)
To: Larry Finger; +Cc: linux-wireless, Larry Finger
In-Reply-To: <20170110161526.22255-1-Larry.Finger@lwfinger.net>
Larry Finger <Larry.Finger@lwfinger.net> wrote:
> In commit c93ac39da0064 ("rtlwifi: Remove some redundant code), a goto
> statement was inadvertently left in the code.
>
> Fixes: c93ac39da0064 ("rtlwifi: Remove some redundant code)
> Reported-by: kbuild test robot <fengguang.wu@intel.com>
> Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Patch applied to wireless-drivers-next.git, thanks.
7f2f61377bca rtlwifi: rtl8192de: Remove a pointless goto
--
https://patchwork.kernel.org/patch/9508121/
Documentation about submitting wireless patches and checking status
from patchwork:
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
^ permalink raw reply
* Re: mwifiex: debugfs: Fix (sometimes) off-by-1 SSID print
From: Kalle Valo @ 2017-01-17 12:03 UTC (permalink / raw)
To: Brian Norris
Cc: Amitkumar Karwar, Nishant Sarmukadam, linux-kernel,
linux-wireless, Cathy Luo, Brian Norris
In-Reply-To: <20170109233350.134036-1-briannorris@chromium.org>
Brian Norris <briannorris@chromium.org> wrote:
> Similar to commit fcd2042e8d36 ("mwifiex: printk() overflow with 32-byte
> SSIDs"), we failed to account for the existence of 32-char SSIDs in our
> debugfs code. Unlike in that case though, we zeroed out the containing
> struct first, and I'm pretty sure we're guaranteed to have some padding
> after the 'ssid.ssid' and 'ssid.ssid_len' fields (the struct is 33 bytes
> long).
>
> So, this is the difference between:
>
> # cat /sys/kernel/debug/mwifiex/mlan0/info
> ...
> essid="0123456789abcdef0123456789abcdef "
> ...
>
> and the correct output:
>
> # cat /sys/kernel/debug/mwifiex/mlan0/info
> ...
> essid="0123456789abcdef0123456789abcdef"
> ...
>
> Fixes: 5e6e3a92b9a4 ("wireless: mwifiex: initial commit for Marvell mwifiex driver")
> Signed-off-by: Brian Norris <briannorris@chromium.org>
Patch applied to wireless-drivers-next.git, thanks.
6183468a23fc mwifiex: debugfs: Fix (sometimes) off-by-1 SSID print
--
https://patchwork.kernel.org/patch/9506069/
Documentation about submitting wireless patches and checking status
from patchwork:
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
^ permalink raw reply
* Re: [V3] brcmfmac: avoid writing channel out of allocated array
From: Kalle Valo @ 2017-01-17 11:57 UTC (permalink / raw)
To: Rafał Miłecki
Cc: Arend van Spriel, Franky Lin, Hante Meuleman,
Pieter-Paul Giesberts, Franky Lin, linux-wireless,
brcm80211-dev-list.pdl, Rafał Miłecki
In-Reply-To: <20170104110941.21261-1-zajec5@gmail.com>
Rafał Miłecki wrote:
> From: Rafał Miłecki <rafal@milecki.pl>
>
> Our code was assigning number of channels to the index variable by
> default. If firmware reported channel we didn't predict this would
> result in using that initial index value and writing out of array. This
> never happened so far (we got a complete list of supported channels) but
> it means possible memory corruption so we should handle it anyway.
>
> This patch simply detects unexpected channel and ignores it.
>
> As we don't try to create new entry now, it's also safe to drop hw_value
> and center_freq assignment. For known channels we have these set anyway.
>
> I decided to fix this issue by assigning NULL or a target channel to the
> channel variable. This was one of possible ways, I prefefred this one as
> it also avoids using channel[index] over and over.
>
> Fixes: 58de92d2f95e ("brcmfmac: use static superset of channels for wiphy bands")
> Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
> Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
Patch applied to wireless-drivers-next.git, thanks.
77c0d0cd10e7 brcmfmac: avoid writing channel out of allocated array
--
https://patchwork.kernel.org/patch/9496471/
Documentation about submitting wireless patches and checking status
from patchwork:
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
^ permalink raw reply
* Re: [1/2] brcmfmac: don't preset all channels as disabled
From: Kalle Valo @ 2017-01-17 12:01 UTC (permalink / raw)
To: Rafał Miłecki
Cc: Arend van Spriel, Franky Lin, Hante Meuleman,
Pieter-Paul Giesberts, Franky Lin, linux-wireless,
brcm80211-dev-list.pdl, Rafał Miłecki
In-Reply-To: <20170107203605.24866-1-zajec5@gmail.com>
Rafał Miłecki wrote:
> From: Rafał Miłecki <rafal@milecki.pl>
>
> During init we take care of regulatory stuff by disabling all
> unavailable channels (see brcmf_construct_chaninfo) so this predisabling
> them is not really required (and this patch won't change any behavior).
> It will on the other hand allow more detailed runtime control over
> channels which is the main reason for this change.
>
> Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
2 patches applied to wireless-drivers-next.git, thanks.
9ea0c307609f brcmfmac: don't preset all channels as disabled
ab99063f8737 brcmfmac: setup wiphy bands after registering it first
--
https://patchwork.kernel.org/patch/9503277/
Documentation about submitting wireless patches and checking status
from patchwork:
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
^ permalink raw reply
* Re: [1/9] rt2800usb: remove watchdog
From: Kalle Valo @ 2017-01-17 11:59 UTC (permalink / raw)
To: Stanislaw Gruszka; +Cc: linux-wireless, Helmut Schaa, Mathias Kresin
In-Reply-To: <1483707918-31480-2-git-send-email-sgruszka@redhat.com>
Stanislaw Gruszka <sgruszka@redhat.com> wrote:
> On rt2800usb, if we do not get TX status from HW, we assume frames were
> posted and after entry->last_action timeout, we forcibly provide TX
> status to mac80211. So it's not possible to detect hardware TX hung
> based on the timeout. Additionally TXRQ_PCNT tells on number of frames
> in the Packet Buffer (buffer between bus interface and chip MAC
> subsystem), which can be non zero on normal conditions. To check HW hung
> we will need provide some different mechanism, for now remove watchdog
> as current implementation is wrong and not useful.
>
> Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
8 patches applied to wireless-drivers-next.git, thanks.
480b468625da rt2800usb: remove watchdog
cfe82fbd8423 rt2800: increase TX timeout
15ec51b25e05 rt2x00: save conf settings before reset tuner
01d97ef4b25f rt2800: change default retry settings
e4019e7f9530 rt2800: tune TX_RTS_CFG config
170122169676 rt2800usb: mark tx failure on timeout
51583248187c rt2x00: do not flush empty queue
66ecec02e851 rt2800: set max_psdu to 3 on usb devices
--
https://patchwork.kernel.org/patch/9500917/
Documentation about submitting wireless patches and checking status
from patchwork:
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
^ permalink raw reply
* Re: mwifiex: fix uninitialized variable access in pcie_remove
From: Kalle Valo @ 2017-01-17 11:55 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Amitkumar Karwar, Arnd Bergmann, Nishant Sarmukadam, Brian Norris,
Xinming Hu, Cathy Luo, Shengzhen Li, linux-wireless, netdev,
linux-kernel
In-Reply-To: <20170113153534.2617372-1-arnd@arndb.de>
Arnd Bergmann <arnd@arndb.de> wrote:
> Checking the firmware status from PCIe register only works
> if the register is available, otherwise we end up with
> random behavior:
>
> drivers/net/wireless/marvell/mwifiex/pcie.c: In function 'mwifiex_pcie_remove':
> drivers/net/wireless/marvell/mwifiex/pcie.c:585:5: error: 'fw_status' may be used uninitialized in this function [-Werror=maybe-uninitialized]
>
> This makes sure we treat the absence of the register as a failure.
>
> Fixes: 045f0c1b5e26 ("mwifiex: get rid of global user_rmmod flag")
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Patch applied to wireless-drivers-next.git, thanks.
0e8edb9aed03 mwifiex: fix uninitialized variable access in pcie_remove
--
https://patchwork.kernel.org/patch/9515899/
Documentation about submitting wireless patches and checking status
from patchwork:
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
^ permalink raw reply
* Re: linux-next: build warning after merge of the wireless-drivers-next tree
From: Kalle Valo @ 2017-01-17 11:49 UTC (permalink / raw)
To: Stephen Rothwell
Cc: Wireless, linux-next, linux-kernel, Xinming Hu, Amitkumar Karwar
In-Reply-To: <87shonjcle.fsf@codeaurora.org>
Kalle Valo <kvalo@codeaurora.org> writes:
> Stephen Rothwell <sfr@canb.auug.org.au> writes:
>
>> Hi all,
>>
>> After merging the wireless-drivers-next tree, today's linux-next build
>> (x86_64 allmodconfig) produced this warning:
>>
>> drivers/net/wireless/marvell/mwifiex/pcie.c: In function 'mwifiex_pcie_remove':
>> drivers/net/wireless/marvell/mwifiex/pcie.c:303:5: warning: 'fw_status' may be used uninitialized in this function [-Wmaybe-uninitialized]
>> if (fw_status == FIRMWARE_READY_PCIE && !adapter->mfg_mode) {
>> ^
>>
>> Introduced by commit
>>
>> 045f0c1b5e26 ("mwifiex: get rid of global user_rmmod flag")
>>
>> This is not a false positive since "reg" could be NULL just above
>> (otherwise it would be tested for).
>
> Thanks, I noticed this myself yesterday (after I had applied the patch)
> and I have asked Marvell to send a fix.
I missed that Arnd had already sent a fix, I'll apply that one:
mwifiex: fix uninitialized variable access in pcie_remove
https://patchwork.kernel.org/patch/9515899/
--
Kalle Valo
^ permalink raw reply
* Re: [1/2] mwifiex: code rearrangement in pcie.c and sdio.c
From: Kalle Valo @ 2017-01-17 11:10 UTC (permalink / raw)
To: Amitkumar Karwar
Cc: linux-wireless@vger.kernel.org, Cathy Luo, Nishant Sarmukadam,
rajatja@google.com, briannorris@google.com,
dmitry.torokhov@gmail.com, Xinming Hu
In-Reply-To: <01b93ecb7f4e43799ff6a9087daed1b5@SC-EXCH04.marvell.com>
Amitkumar Karwar <akarwar@marvell.com> writes:
> Hi Kalle,
>
>> From: Kalle Valo [mailto:kvalo@codeaurora.org]
>> Sent: Thursday, January 12, 2017 8:25 PM
>> To: Amitkumar Karwar
>> Cc: linux-wireless@vger.kernel.org; Cathy Luo; Nishant Sarmukadam;
>> rajatja@google.com; briannorris@google.com; dmitry.torokhov@gmail.com;
>> Xinming Hu
>> Subject: Re: [1/2] mwifiex: code rearrangement in pcie.c and sdio.c
>>
>> Amitkumar Karwar <akarwar@marvell.com> writes:
>>
>> >> But these didn't. Can you please rebase these and resubmit in one
>> >> patchset? Less conflicts that way.
>> >>
>> >
>> > The problem here is you tried to apply the patches in reverse order.
>> Sorry for the confusion.
>> > Please apply pending patches in below order.
>> >
>> > [v3,1/5] mwifiex: don't wait for main_process in shutdown_drv ---
>> Apply this patch first.
>> > [v3,2/5] mwifiex: do not free firmware dump memory in shutdown_drv
>> > [v3,3/5] mwifiex: get rid of drv_info* adapter variables [v3,4/5]
>> > mwifiex: wait firmware dump complete during card remove process
>> > [v3,5/5] mwifiex: move pcie_work and related variables inside card
>> >
>> > [1/2] mwifiex: code rearrangement in pcie.c and sdio.c [2/2] mwifiex:
>> > get rid of global user_rmmod flag
>> >
>> > mwifiex: use module_*_driver helper macros
>> >
>> > [1/5] mwifiex: get rid of mwifiex_do_flr wrapper [2/5] mwifiex:
>> > cleanup in PCIe flr code path [3/5] mwifiex: sdio card reset
>> > enhancement [4/5] mwifiex: get rid of __mwifiex_sdio_remove helper
>> > [5/5] mwifiex: get rid of global save_adapter and sdio_work
>>
>> Thanks, now I was able to apply these but please do double check the
>> result in wireless-drivers-next.
>>
>> I also noticed a new warning:
>>
>> drivers/net/wireless/marvell/mwifiex/pcie.c: In function
>> 'mwifiex_pcie_remove':
>> drivers/net/wireless/marvell/mwifiex/pcie.c:303:5: warning: 'fw_status'
>> may be used uninitialized in this function [-Wmaybe-uninitialized]
>> if (fw_status == FIRMWARE_READY_PCIE && !adapter->mfg_mode) {
>>
>> Actually I'm not sure if this warning was caused by these patches as I
>> have recently updated my ancient gcc to a newer one (5.4.0), but please
>> take a look and send a fix if it's a valid warning.
>>
>
> Below CL fixes this warning.
>
> https://patchwork.kernel.org/patch/9515899/
Good, thanks. I'll apply that shortly.
--
Kalle Valo
^ permalink raw reply
* Re: [PATCH V2] mtd: bcm47xxsflash: use platform_(set|get)_drvdata
From: Kalle Valo @ 2017-01-17 11:07 UTC (permalink / raw)
To: Rafał Miłecki
Cc: David Woodhouse, Brian Norris, Boris Brezillon, Marek Vasut,
Richard Weinberger, Cyrille Pitchen, linux-mtd, linux-wireless,
Hauke Mehrtens, Rafał Miłecki
In-Reply-To: <20170116162818.12094-1-zajec5@gmail.com>
Rafa=C5=82 Mi=C5=82ecki <zajec5@gmail.com> writes:
> From: Rafa=C5=82 Mi=C5=82ecki <rafal@milecki.pl>
>
> We have generic place & helpers for storing platform driver data so
> there is no reason for using custom priv pointer.
>
> This allows cleaning up struct bcma_sflash from unneeded fields.
>
> Signed-off-by: Rafa=C5=82 Mi=C5=82ecki <rafal@milecki.pl>
> ---
> Kalle: This is mtd focused patch, so I guess it should go through mtd tre=
e. Do
> you find bcma change important enough to care to Ack it? :)
Sure :)
Feel free to take the patch via mtd tree, I'm not expecting to see any
conflicts with this patch. For the bcma part:
Acked-by: Kalle Valo <kvalo@codeaurora.org>
--=20
Kalle Valo
^ permalink raw reply
* RE: [1/2] mwifiex: code rearrangement in pcie.c and sdio.c
From: Amitkumar Karwar @ 2017-01-17 8:34 UTC (permalink / raw)
To: Kalle Valo
Cc: linux-wireless@vger.kernel.org, Cathy Luo, Nishant Sarmukadam,
rajatja@google.com, briannorris@google.com,
dmitry.torokhov@gmail.com, Xinming Hu
In-Reply-To: <87lgugnx9f.fsf@kamboji.qca.qualcomm.com>
Hi Kalle,
> From: Kalle Valo [mailto:kvalo@codeaurora.org]
> Sent: Thursday, January 12, 2017 8:25 PM
> To: Amitkumar Karwar
> Cc: linux-wireless@vger.kernel.org; Cathy Luo; Nishant Sarmukadam;
> rajatja@google.com; briannorris@google.com; dmitry.torokhov@gmail.com;
> Xinming Hu
> Subject: Re: [1/2] mwifiex: code rearrangement in pcie.c and sdio.c
>
> Amitkumar Karwar <akarwar@marvell.com> writes:
>
> >> But these didn't. Can you please rebase these and resubmit in one
> >> patchset? Less conflicts that way.
> >>
> >
> > The problem here is you tried to apply the patches in reverse order.
> Sorry for the confusion.
> > Please apply pending patches in below order.
> >
> > [v3,1/5] mwifiex: don't wait for main_process in shutdown_drv ---
> Apply this patch first.
> > [v3,2/5] mwifiex: do not free firmware dump memory in shutdown_drv
> > [v3,3/5] mwifiex: get rid of drv_info* adapter variables [v3,4/5]
> > mwifiex: wait firmware dump complete during card remove process
> > [v3,5/5] mwifiex: move pcie_work and related variables inside card
> >
> > [1/2] mwifiex: code rearrangement in pcie.c and sdio.c [2/2] mwifiex:
> > get rid of global user_rmmod flag
> >
> > mwifiex: use module_*_driver helper macros
> >
> > [1/5] mwifiex: get rid of mwifiex_do_flr wrapper [2/5] mwifiex:
> > cleanup in PCIe flr code path [3/5] mwifiex: sdio card reset
> > enhancement [4/5] mwifiex: get rid of __mwifiex_sdio_remove helper
> > [5/5] mwifiex: get rid of global save_adapter and sdio_work
>
> Thanks, now I was able to apply these but please do double check the
> result in wireless-drivers-next.
>
> I also noticed a new warning:
>
> drivers/net/wireless/marvell/mwifiex/pcie.c: In function
> 'mwifiex_pcie_remove':
> drivers/net/wireless/marvell/mwifiex/pcie.c:303:5: warning: 'fw_status'
> may be used uninitialized in this function [-Wmaybe-uninitialized]
> if (fw_status == FIRMWARE_READY_PCIE && !adapter->mfg_mode) {
>
> Actually I'm not sure if this warning was caused by these patches as I
> have recently updated my ancient gcc to a newer one (5.4.0), but please
> take a look and send a fix if it's a valid warning.
>
Below CL fixes this warning.
https://patchwork.kernel.org/patch/9515899/
Regards,
Amitkumar
^ permalink raw reply
* Re: [PATCH v2 09/14] rt2x00: rt2x00pci: set PCI MWI only if supported
From: John Crispin @ 2017-01-17 7:34 UTC (permalink / raw)
To: Daniel Golle, Stanislaw Gruszka
Cc: linux-wireless, Johannes Berg, roman, michel.stempin, c.mignanti,
evaxige, Kalle Valo, Felix Fietkau, Gabor Juhos
In-Reply-To: <20170117015653.GF1912@makrotopia.org>
On 17/01/2017 02:56, Daniel Golle wrote:
> On Mon, Jan 16, 2017 at 11:08:57AM +0100, Stanislaw Gruszka wrote:
>> On Mon, Jan 16, 2017 at 04:06:25AM +0100, Daniel Golle wrote:
>>> From: Claudio Mignanti <c.mignanti@gmail.com>
>>>
>>> This is needed for devices without support for PCI MWI. See also
>>> https://dev.openwrt.org/changeset/21850
>>>
>>> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
>>> ---
>>> drivers/net/wireless/ralink/rt2x00/rt2x00pci.c | 2 ++
>>> 1 file changed, 2 insertions(+)
>>>
>>> diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00pci.c b/drivers/net/wireless/ralink/rt2x00/rt2x00pci.c
>>> index eb6dbcd4fddf..4becfeb75ba8 100644
>>> --- a/drivers/net/wireless/ralink/rt2x00/rt2x00pci.c
>>> +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00pci.c
>>> @@ -94,8 +94,10 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops)
>>>
>>> pci_set_master(pci_dev);
>>>
>>> +#ifdef CONFIG_PCI_SET_MWI
>>> if (pci_set_mwi(pci_dev))
>>> rt2x00_probe_err("MWI not available\n");
>>> +#endif
>>
>> There is no CONFIG_PCI_SET_MWI in the kernel. This patch is either not
>> needed (pci subsystem has own PCI_DISABLE_MWI define) or wrong (we
>> should not call this function for some devices).
>
> Apparently we thus never enabled MWI on PCI devices. John Crispin has
> started to investigate why this patch was needed in first place, see
> http://lists.infradead.org/pipermail/lede-dev/2017-January/005400.html
>
> I suggest to drop it entirely until we figure out why it wasn't safe to
> use MWI at least on some platforms. Once we know more there might be
> a follow-up to selectively have the precompiler skip pci_set_mwi in
> case we really still need to do this.
> Aparently this was originally related to a compiler error on Kernel
> 2.6.30 when trying to build for Rt305x WiSoC platforms (which simply
> do not have any PCI bus and probably explicite support for SoC devices
> wasn't implemented in rt2x00 at the time).
>
>
here is the original thread related to this patch
http://rt2x00.serialmonkey.com/pipermail/users_rt2x00.serialmonkey.com/2012-November/012227.html
John
> Cheers
>
>
> Daniel
>
>>
>> Stanislaw
^ permalink raw reply
* Re: [PATCH v2 09/14] rt2x00: rt2x00pci: set PCI MWI only if supported
From: Daniel Golle @ 2017-01-17 1:56 UTC (permalink / raw)
To: Stanislaw Gruszka
Cc: linux-wireless, Johannes Berg, roman, michel.stempin, c.mignanti,
evaxige, Kalle Valo, Felix Fietkau, John Crispin, Gabor Juhos
In-Reply-To: <20170116100856.GB6968@redhat.com>
On Mon, Jan 16, 2017 at 11:08:57AM +0100, Stanislaw Gruszka wrote:
> On Mon, Jan 16, 2017 at 04:06:25AM +0100, Daniel Golle wrote:
> > From: Claudio Mignanti <c.mignanti@gmail.com>
> >
> > This is needed for devices without support for PCI MWI. See also
> > https://dev.openwrt.org/changeset/21850
> >
> > Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> > ---
> > drivers/net/wireless/ralink/rt2x00/rt2x00pci.c | 2 ++
> > 1 file changed, 2 insertions(+)
> >
> > diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00pci.c b/drivers/net/wireless/ralink/rt2x00/rt2x00pci.c
> > index eb6dbcd4fddf..4becfeb75ba8 100644
> > --- a/drivers/net/wireless/ralink/rt2x00/rt2x00pci.c
> > +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00pci.c
> > @@ -94,8 +94,10 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops)
> >
> > pci_set_master(pci_dev);
> >
> > +#ifdef CONFIG_PCI_SET_MWI
> > if (pci_set_mwi(pci_dev))
> > rt2x00_probe_err("MWI not available\n");
> > +#endif
>
> There is no CONFIG_PCI_SET_MWI in the kernel. This patch is either not
> needed (pci subsystem has own PCI_DISABLE_MWI define) or wrong (we
> should not call this function for some devices).
Apparently we thus never enabled MWI on PCI devices. John Crispin has
started to investigate why this patch was needed in first place, see
http://lists.infradead.org/pipermail/lede-dev/2017-January/005400.html
I suggest to drop it entirely until we figure out why it wasn't safe to
use MWI at least on some platforms. Once we know more there might be
a follow-up to selectively have the precompiler skip pci_set_mwi in
case we really still need to do this.
Aparently this was originally related to a compiler error on Kernel
2.6.30 when trying to build for Rt305x WiSoC platforms (which simply
do not have any PCI bus and probably explicite support for SoC devices
wasn't implemented in rt2x00 at the time).
Cheers
Daniel
>
> Stanislaw
^ permalink raw reply
* Re: [PATCH v2 14/14] rt2x00: add support for RT5350 WiSoC
From: Daniel Golle @ 2017-01-17 1:48 UTC (permalink / raw)
To: Stanislaw Gruszka
Cc: linux-wireless, Johannes Berg, roman, michel.stempin, c.mignanti,
evaxige, Kalle Valo, Felix Fietkau, John Crispin, Gabor Juhos
In-Reply-To: <20170116101743.GF6968@redhat.com>
On Mon, Jan 16, 2017 at 11:17:44AM +0100, Stanislaw Gruszka wrote:
> On Mon, Jan 16, 2017 at 04:17:58AM +0100, Daniel Golle wrote:
> > @@ -7131,6 +7236,12 @@ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
> > rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RF_TYPE, RF2820);
> > rt2800_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word);
> > rt2x00_eeprom_dbg(rt2x00dev, "Antenna: 0x%04x\n", word);
> > + } else if (rt2x00_rt(rt2x00dev, RT5350)) {
> > + rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RXPATH, 1);
> > + rt2x00_set_field16(&word, EEPROM_NIC_CONF0_TXPATH, 1);
> > + rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RF_TYPE, RF3320);
Good catch. This line was probably left over when trying to implement
support for RT5350 based on adding codepaths to RF3320 which ended up
messy... As EEPROM_NIC_CONF0_RF_TYPE aparently isn't used anywhere else
in the code apart from setting rf type which is later on overwritten
for RT5350 anyway. So no need to set it at all. I suggest to simply
drop that line.
>
> Here you set RF3320 ..
> > + rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word);
> > + rt2x00_eeprom_dbg(rt2x00dev, "Antenna: 0x%04x\n", word);
> > } else if (rt2x00_rt(rt2x00dev, RT2860) ||
> > rt2x00_rt(rt2x00dev, RT2872)) {
> > /*
> > @@ -7265,6 +7376,8 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
> > rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
> > else if (rt2x00_rt(rt2x00dev, RT3352))
> > rf = RF3322;
> > + else if (rt2x00_rt(rt2x00dev, RT5350))
> > + rf = RF5350;
>
> and here RF5350. This does not seems to be correct.
>
> Stanislaw
^ permalink raw reply
* Re: brcmfmac: add support for BCM43455 with modalias sdio:c00v02D0dA9BF
From: Andreas Färber @ 2017-01-17 0:19 UTC (permalink / raw)
To: Martin Blumenstingl, linux-mmc, brcm80211-dev-list.pdl,
linux-wireless, kvalo, ulf.hansson
Cc: arend.vanspriel, franky.lin, hante.meuleman
In-Reply-To: <20170116101757.20483-1-martin.blumenstingl@googlemail.com>
Hi Martin,
Am 16.01.2017 um 11:17 schrieb Martin Blumenstingl:
> BCM43455 is a more recent revision of the BCM4345. Some of the BCM43455
> got a dedicated SDIO device ID which is currently not supported by
> brcmfmac.
> Adding the new sdio_device_id to brcmfmac is enough to get the BCM43455
> supported because the chip itself is already supported (due to BCM4345
> support in the driver).
>
> Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
> Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
> ---
> This is the proper patch following the (short) discussion from [0]
>
> [0] https://marc.info/?l=linux-wireless&m=148455981002310&w=2
>
> drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 1 +
> include/linux/mmc/sdio_ids.h | 1 +
> 2 files changed, 2 insertions(+)
Reviewed-by: Andreas Färber <afaerber@suse.de>
I encountered the same ID on my R-Box Pro 3G and tested the exact same
patch based on [0] there:
[ +0,130866] brcmfmac: brcmf_c_preinit_dcmds: Firmware version = wl0:
Mar 1 2015 07:29:38 version 7.45.18 (r538002) FWID 01-6a2c8ad4
...
[ +0,156118] brcmfmac: brcmf_cfg80211_reg_notifier: not a ISO3166 code
(0x30 0x30)
...
[ +1,790419] brcmfmac: brcmf_cfg80211_reg_notifier: not a ISO3166 code
(0x30 0x30)
Tested-by: Andreas Färber <afaerber@suse.de>
Thanks,
Andreas
--
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
^ 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