Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net

Conflicts:
	drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
	net/bridge/br_multicast.c
	net/ipv6/sit.c

The conflicts were minor:

1) sit.c changes overlap with change to ip_tunnel_xmit() signature.

2) br_multicast.c had an overlap between computing max_delay using
   msecs_to_jiffies and turning MLDV2_MRC() into an inline function
   with a name using lowercase instead of uppercase letters.

3) stmmac had two overlapping changes, one which conditionally allocated
   and hooked up a dma_cfg based upon the presence of the pbl OF property,
   and another one handling store-and-forward DMA made.  The latter of
   which should not go into the new of_find_property() basic block.

Signed-off-by: David S. Miller <[email protected]>
This commit is contained in:
David S. Miller 2013-09-05 14:58:52 -04:00
commit 06c54055be
143 changed files with 1483 additions and 684 deletions

View file

@ -71,7 +71,7 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
mdst = br_mdb_get(br, skb, vid);
if ((mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) &&
br_multicast_querier_exists(br))
br_multicast_querier_exists(br, eth_hdr(skb)))
br_multicast_deliver(mdst, skb);
else
br_flood_deliver(br, skb, false);

View file

@ -102,7 +102,7 @@ int br_handle_frame_finish(struct sk_buff *skb)
} else if (is_multicast_ether_addr(dest)) {
mdst = br_mdb_get(br, skb, vid);
if ((mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) &&
br_multicast_querier_exists(br)) {
br_multicast_querier_exists(br, eth_hdr(skb))) {
if ((mdst && mdst->mglist) ||
br_multicast_is_router(br))
skb2 = skb;

View file

@ -416,16 +416,20 @@ static int __br_mdb_del(struct net_bridge *br, struct br_mdb_entry *entry)
if (!netif_running(br->dev) || br->multicast_disabled)
return -EINVAL;
if (timer_pending(&br->multicast_querier_timer))
return -EBUSY;
ip.proto = entry->addr.proto;
if (ip.proto == htons(ETH_P_IP))
if (ip.proto == htons(ETH_P_IP)) {
if (timer_pending(&br->ip4_querier.timer))
return -EBUSY;
ip.u.ip4 = entry->addr.u.ip4;
#if IS_ENABLED(CONFIG_IPV6)
else
} else {
if (timer_pending(&br->ip6_querier.timer))
return -EBUSY;
ip.u.ip6 = entry->addr.u.ip6;
#endif
}
spin_lock_bh(&br->multicast_lock);
mdb = mlock_dereference(br->mdb, br);

View file

@ -34,7 +34,8 @@
#include "br_private.h"
static void br_multicast_start_querier(struct net_bridge *br);
static void br_multicast_start_querier(struct net_bridge *br,
struct bridge_mcast_query *query);
unsigned int br_mdb_rehash_seq;
static inline int br_ip_equal(const struct br_ip *a, const struct br_ip *b)
@ -756,20 +757,35 @@ static void br_multicast_local_router_expired(unsigned long data)
{
}
static void br_multicast_querier_expired(unsigned long data)
static void br_multicast_querier_expired(struct net_bridge *br,
struct bridge_mcast_query *query)
{
struct net_bridge *br = (void *)data;
spin_lock(&br->multicast_lock);
if (!netif_running(br->dev) || br->multicast_disabled)
goto out;
br_multicast_start_querier(br);
br_multicast_start_querier(br, query);
out:
spin_unlock(&br->multicast_lock);
}
static void br_ip4_multicast_querier_expired(unsigned long data)
{
struct net_bridge *br = (void *)data;
br_multicast_querier_expired(br, &br->ip4_query);
}
#if IS_ENABLED(CONFIG_IPV6)
static void br_ip6_multicast_querier_expired(unsigned long data)
{
struct net_bridge *br = (void *)data;
br_multicast_querier_expired(br, &br->ip6_query);
}
#endif
static void __br_multicast_send_query(struct net_bridge *br,
struct net_bridge_port *port,
struct br_ip *ip)
@ -790,37 +806,45 @@ static void __br_multicast_send_query(struct net_bridge *br,
}
static void br_multicast_send_query(struct net_bridge *br,
struct net_bridge_port *port, u32 sent)
struct net_bridge_port *port,
struct bridge_mcast_query *query)
{
unsigned long time;
struct br_ip br_group;
struct bridge_mcast_querier *querier = NULL;
if (!netif_running(br->dev) || br->multicast_disabled ||
!br->multicast_querier ||
timer_pending(&br->multicast_querier_timer))
!br->multicast_querier)
return;
memset(&br_group.u, 0, sizeof(br_group.u));
br_group.proto = htons(ETH_P_IP);
__br_multicast_send_query(br, port, &br_group);
if (port ? (query == &port->ip4_query) :
(query == &br->ip4_query)) {
querier = &br->ip4_querier;
br_group.proto = htons(ETH_P_IP);
#if IS_ENABLED(CONFIG_IPV6)
br_group.proto = htons(ETH_P_IPV6);
__br_multicast_send_query(br, port, &br_group);
} else {
querier = &br->ip6_querier;
br_group.proto = htons(ETH_P_IPV6);
#endif
}
if (!querier || timer_pending(&querier->timer))
return;
__br_multicast_send_query(br, port, &br_group);
time = jiffies;
time += sent < br->multicast_startup_query_count ?
time += query->startup_sent < br->multicast_startup_query_count ?
br->multicast_startup_query_interval :
br->multicast_query_interval;
mod_timer(port ? &port->multicast_query_timer :
&br->multicast_query_timer, time);
mod_timer(&query->timer, time);
}
static void br_multicast_port_query_expired(unsigned long data)
static void br_multicast_port_query_expired(struct net_bridge_port *port,
struct bridge_mcast_query *query)
{
struct net_bridge_port *port = (void *)data;
struct net_bridge *br = port->br;
spin_lock(&br->multicast_lock);
@ -828,25 +852,43 @@ static void br_multicast_port_query_expired(unsigned long data)
port->state == BR_STATE_BLOCKING)
goto out;
if (port->multicast_startup_queries_sent <
br->multicast_startup_query_count)
port->multicast_startup_queries_sent++;
if (query->startup_sent < br->multicast_startup_query_count)
query->startup_sent++;
br_multicast_send_query(port->br, port,
port->multicast_startup_queries_sent);
br_multicast_send_query(port->br, port, query);
out:
spin_unlock(&br->multicast_lock);
}
static void br_ip4_multicast_port_query_expired(unsigned long data)
{
struct net_bridge_port *port = (void *)data;
br_multicast_port_query_expired(port, &port->ip4_query);
}
#if IS_ENABLED(CONFIG_IPV6)
static void br_ip6_multicast_port_query_expired(unsigned long data)
{
struct net_bridge_port *port = (void *)data;
br_multicast_port_query_expired(port, &port->ip6_query);
}
#endif
void br_multicast_add_port(struct net_bridge_port *port)
{
port->multicast_router = 1;
setup_timer(&port->multicast_router_timer, br_multicast_router_expired,
(unsigned long)port);
setup_timer(&port->multicast_query_timer,
br_multicast_port_query_expired, (unsigned long)port);
setup_timer(&port->ip4_query.timer, br_ip4_multicast_port_query_expired,
(unsigned long)port);
#if IS_ENABLED(CONFIG_IPV6)
setup_timer(&port->ip6_query.timer, br_ip6_multicast_port_query_expired,
(unsigned long)port);
#endif
}
void br_multicast_del_port(struct net_bridge_port *port)
@ -854,13 +896,13 @@ void br_multicast_del_port(struct net_bridge_port *port)
del_timer_sync(&port->multicast_router_timer);
}
static void __br_multicast_enable_port(struct net_bridge_port *port)
static void br_multicast_enable(struct bridge_mcast_query *query)
{
port->multicast_startup_queries_sent = 0;
query->startup_sent = 0;
if (try_to_del_timer_sync(&port->multicast_query_timer) >= 0 ||
del_timer(&port->multicast_query_timer))
mod_timer(&port->multicast_query_timer, jiffies);
if (try_to_del_timer_sync(&query->timer) >= 0 ||
del_timer(&query->timer))
mod_timer(&query->timer, jiffies);
}
void br_multicast_enable_port(struct net_bridge_port *port)
@ -871,7 +913,10 @@ void br_multicast_enable_port(struct net_bridge_port *port)
if (br->multicast_disabled || !netif_running(br->dev))
goto out;
__br_multicast_enable_port(port);
br_multicast_enable(&port->ip4_query);
#if IS_ENABLED(CONFIG_IPV6)
br_multicast_enable(&port->ip6_query);
#endif
out:
spin_unlock(&br->multicast_lock);
@ -890,7 +935,10 @@ void br_multicast_disable_port(struct net_bridge_port *port)
if (!hlist_unhashed(&port->rlist))
hlist_del_init_rcu(&port->rlist);
del_timer(&port->multicast_router_timer);
del_timer(&port->multicast_query_timer);
del_timer(&port->ip4_query.timer);
#if IS_ENABLED(CONFIG_IPV6)
del_timer(&port->ip6_query.timer);
#endif
spin_unlock(&br->multicast_lock);
}
@ -1015,14 +1063,15 @@ static int br_ip6_multicast_mld2_report(struct net_bridge *br,
}
#endif
static void br_multicast_update_querier_timer(struct net_bridge *br,
unsigned long max_delay)
static void
br_multicast_update_querier_timer(struct net_bridge *br,
struct bridge_mcast_querier *querier,
unsigned long max_delay)
{
if (!timer_pending(&br->multicast_querier_timer))
br->multicast_querier_delay_time = jiffies + max_delay;
if (!timer_pending(&querier->timer))
querier->delay_time = jiffies + max_delay;
mod_timer(&br->multicast_querier_timer,
jiffies + br->multicast_querier_interval);
mod_timer(&querier->timer, jiffies + br->multicast_querier_interval);
}
/*
@ -1075,12 +1124,13 @@ timer:
static void br_multicast_query_received(struct net_bridge *br,
struct net_bridge_port *port,
struct bridge_mcast_querier *querier,
int saddr,
unsigned long max_delay)
{
if (saddr)
br_multicast_update_querier_timer(br, max_delay);
else if (timer_pending(&br->multicast_querier_timer))
br_multicast_update_querier_timer(br, querier, max_delay);
else if (timer_pending(&querier->timer))
return;
br_multicast_mark_router(br, port);
@ -1130,7 +1180,8 @@ static int br_ip4_multicast_query(struct net_bridge *br,
IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE) : 1;
}
br_multicast_query_received(br, port, !!iph->saddr, max_delay);
br_multicast_query_received(br, port, &br->ip4_querier, !!iph->saddr,
max_delay);
if (!group)
goto out;
@ -1208,8 +1259,8 @@ static int br_ip6_multicast_query(struct net_bridge *br,
max_delay = max(msecs_to_jiffies(mldv2_mrc(mld2q)), 1UL);
}
br_multicast_query_received(br, port, !ipv6_addr_any(&ip6h->saddr),
max_delay);
br_multicast_query_received(br, port, &br->ip6_querier,
!ipv6_addr_any(&ip6h->saddr), max_delay);
if (!group)
goto out;
@ -1246,7 +1297,9 @@ out:
static void br_multicast_leave_group(struct net_bridge *br,
struct net_bridge_port *port,
struct br_ip *group)
struct br_ip *group,
struct bridge_mcast_querier *querier,
struct bridge_mcast_query *query)
{
struct net_bridge_mdb_htable *mdb;
struct net_bridge_mdb_entry *mp;
@ -1257,7 +1310,7 @@ static void br_multicast_leave_group(struct net_bridge *br,
spin_lock(&br->multicast_lock);
if (!netif_running(br->dev) ||
(port && port->state == BR_STATE_DISABLED) ||
timer_pending(&br->multicast_querier_timer))
timer_pending(&querier->timer))
goto out;
mdb = mlock_dereference(br->mdb, br);
@ -1265,14 +1318,13 @@ static void br_multicast_leave_group(struct net_bridge *br,
if (!mp)
goto out;
if (br->multicast_querier &&
!timer_pending(&br->multicast_querier_timer)) {
if (br->multicast_querier) {
__br_multicast_send_query(br, port, &mp->addr);
time = jiffies + br->multicast_last_member_count *
br->multicast_last_member_interval;
mod_timer(port ? &port->multicast_query_timer :
&br->multicast_query_timer, time);
mod_timer(&query->timer, time);
for (p = mlock_dereference(mp->ports, br);
p != NULL;
@ -1325,7 +1377,6 @@ static void br_multicast_leave_group(struct net_bridge *br,
mod_timer(&mp->timer, time);
}
}
out:
spin_unlock(&br->multicast_lock);
}
@ -1336,6 +1387,8 @@ static void br_ip4_multicast_leave_group(struct net_bridge *br,
__u16 vid)
{
struct br_ip br_group;
struct bridge_mcast_query *query = port ? &port->ip4_query :
&br->ip4_query;
if (ipv4_is_local_multicast(group))
return;
@ -1344,7 +1397,7 @@ static void br_ip4_multicast_leave_group(struct net_bridge *br,
br_group.proto = htons(ETH_P_IP);
br_group.vid = vid;
br_multicast_leave_group(br, port, &br_group);
br_multicast_leave_group(br, port, &br_group, &br->ip4_querier, query);
}
#if IS_ENABLED(CONFIG_IPV6)
@ -1354,6 +1407,9 @@ static void br_ip6_multicast_leave_group(struct net_bridge *br,
__u16 vid)
{
struct br_ip br_group;
struct bridge_mcast_query *query = port ? &port->ip6_query :
&br->ip6_query;
if (ipv6_addr_is_ll_all_nodes(group))
return;
@ -1362,7 +1418,7 @@ static void br_ip6_multicast_leave_group(struct net_bridge *br,
br_group.proto = htons(ETH_P_IPV6);
br_group.vid = vid;
br_multicast_leave_group(br, port, &br_group);
br_multicast_leave_group(br, port, &br_group, &br->ip6_querier, query);
}
#endif
@ -1630,20 +1686,33 @@ int br_multicast_rcv(struct net_bridge *br, struct net_bridge_port *port,
return 0;
}
static void br_multicast_query_expired(unsigned long data)
static void br_multicast_query_expired(struct net_bridge *br,
struct bridge_mcast_query *query)
{
spin_lock(&br->multicast_lock);
if (query->startup_sent < br->multicast_startup_query_count)
query->startup_sent++;
br_multicast_send_query(br, NULL, query);
spin_unlock(&br->multicast_lock);
}
static void br_ip4_multicast_query_expired(unsigned long data)
{
struct net_bridge *br = (void *)data;
spin_lock(&br->multicast_lock);
if (br->multicast_startup_queries_sent <
br->multicast_startup_query_count)
br->multicast_startup_queries_sent++;
br_multicast_send_query(br, NULL, br->multicast_startup_queries_sent);
spin_unlock(&br->multicast_lock);
br_multicast_query_expired(br, &br->ip4_query);
}
#if IS_ENABLED(CONFIG_IPV6)
static void br_ip6_multicast_query_expired(unsigned long data)
{
struct net_bridge *br = (void *)data;
br_multicast_query_expired(br, &br->ip6_query);
}
#endif
void br_multicast_init(struct net_bridge *br)
{
br->hash_elasticity = 4;
@ -1662,25 +1731,43 @@ void br_multicast_init(struct net_bridge *br)
br->multicast_querier_interval = 255 * HZ;
br->multicast_membership_interval = 260 * HZ;
br->multicast_querier_delay_time = 0;
br->ip4_querier.delay_time = 0;
#if IS_ENABLED(CONFIG_IPV6)
br->ip6_querier.delay_time = 0;
#endif
spin_lock_init(&br->multicast_lock);
setup_timer(&br->multicast_router_timer,
br_multicast_local_router_expired, 0);
setup_timer(&br->multicast_querier_timer,
br_multicast_querier_expired, (unsigned long)br);
setup_timer(&br->multicast_query_timer, br_multicast_query_expired,
setup_timer(&br->ip4_querier.timer, br_ip4_multicast_querier_expired,
(unsigned long)br);
setup_timer(&br->ip4_query.timer, br_ip4_multicast_query_expired,
(unsigned long)br);
#if IS_ENABLED(CONFIG_IPV6)
setup_timer(&br->ip6_querier.timer, br_ip6_multicast_querier_expired,
(unsigned long)br);
setup_timer(&br->ip6_query.timer, br_ip6_multicast_query_expired,
(unsigned long)br);
#endif
}
void br_multicast_open(struct net_bridge *br)
static void __br_multicast_open(struct net_bridge *br,
struct bridge_mcast_query *query)
{
br->multicast_startup_queries_sent = 0;
query->startup_sent = 0;
if (br->multicast_disabled)
return;
mod_timer(&br->multicast_query_timer, jiffies);
mod_timer(&query->timer, jiffies);
}
void br_multicast_open(struct net_bridge *br)
{
__br_multicast_open(br, &br->ip4_query);
#if IS_ENABLED(CONFIG_IPV6)
__br_multicast_open(br, &br->ip6_query);
#endif
}
void br_multicast_stop(struct net_bridge *br)
@ -1692,8 +1779,12 @@ void br_multicast_stop(struct net_bridge *br)
int i;
del_timer_sync(&br->multicast_router_timer);
del_timer_sync(&br->multicast_querier_timer);
del_timer_sync(&br->multicast_query_timer);
del_timer_sync(&br->ip4_querier.timer);
del_timer_sync(&br->ip4_query.timer);
#if IS_ENABLED(CONFIG_IPV6)
del_timer_sync(&br->ip6_querier.timer);
del_timer_sync(&br->ip6_query.timer);
#endif
spin_lock_bh(&br->multicast_lock);
mdb = mlock_dereference(br->mdb, br);
@ -1796,18 +1887,24 @@ unlock:
return err;
}
static void br_multicast_start_querier(struct net_bridge *br)
static void br_multicast_start_querier(struct net_bridge *br,
struct bridge_mcast_query *query)
{
struct net_bridge_port *port;
br_multicast_open(br);
__br_multicast_open(br, query);
list_for_each_entry(port, &br->port_list, list) {
if (port->state == BR_STATE_DISABLED ||
port->state == BR_STATE_BLOCKING)
continue;
__br_multicast_enable_port(port);
if (query == &br->ip4_query)
br_multicast_enable(&port->ip4_query);
#if IS_ENABLED(CONFIG_IPV6)
else
br_multicast_enable(&port->ip6_query);
#endif
}
}
@ -1842,7 +1939,10 @@ rollback:
goto rollback;
}
br_multicast_start_querier(br);
br_multicast_start_querier(br, &br->ip4_query);
#if IS_ENABLED(CONFIG_IPV6)
br_multicast_start_querier(br, &br->ip6_query);
#endif
unlock:
spin_unlock_bh(&br->multicast_lock);
@ -1865,10 +1965,18 @@ int br_multicast_set_querier(struct net_bridge *br, unsigned long val)
goto unlock;
max_delay = br->multicast_query_response_interval;
if (!timer_pending(&br->multicast_querier_timer))
br->multicast_querier_delay_time = jiffies + max_delay;
br_multicast_start_querier(br);
if (!timer_pending(&br->ip4_querier.timer))
br->ip4_querier.delay_time = jiffies + max_delay;
br_multicast_start_querier(br, &br->ip4_query);
#if IS_ENABLED(CONFIG_IPV6)
if (!timer_pending(&br->ip6_querier.timer))
br->ip6_querier.delay_time = jiffies + max_delay;
br_multicast_start_querier(br, &br->ip6_query);
#endif
unlock:
spin_unlock_bh(&br->multicast_lock);

View file

@ -66,6 +66,20 @@ struct br_ip
__u16 vid;
};
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
/* our own querier */
struct bridge_mcast_query {
struct timer_list timer;
u32 startup_sent;
};
/* other querier */
struct bridge_mcast_querier {
struct timer_list timer;
unsigned long delay_time;
};
#endif
struct net_port_vlans {
u16 port_idx;
u16 pvid;
@ -162,10 +176,12 @@ struct net_bridge_port
#define BR_FLOOD 0x00000040
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
u32 multicast_startup_queries_sent;
struct bridge_mcast_query ip4_query;
#if IS_ENABLED(CONFIG_IPV6)
struct bridge_mcast_query ip6_query;
#endif /* IS_ENABLED(CONFIG_IPV6) */
unsigned char multicast_router;
struct timer_list multicast_router_timer;
struct timer_list multicast_query_timer;
struct hlist_head mglist;
struct hlist_node rlist;
#endif
@ -258,7 +274,6 @@ struct net_bridge
u32 hash_max;
u32 multicast_last_member_count;
u32 multicast_startup_queries_sent;
u32 multicast_startup_query_count;
unsigned long multicast_last_member_interval;
@ -267,15 +282,18 @@ struct net_bridge
unsigned long multicast_query_interval;
unsigned long multicast_query_response_interval;
unsigned long multicast_startup_query_interval;
unsigned long multicast_querier_delay_time;
spinlock_t multicast_lock;
struct net_bridge_mdb_htable __rcu *mdb;
struct hlist_head router_list;
struct timer_list multicast_router_timer;
struct timer_list multicast_querier_timer;
struct timer_list multicast_query_timer;
struct bridge_mcast_querier ip4_querier;
struct bridge_mcast_query ip4_query;
#if IS_ENABLED(CONFIG_IPV6)
struct bridge_mcast_querier ip6_querier;
struct bridge_mcast_query ip6_query;
#endif /* IS_ENABLED(CONFIG_IPV6) */
#endif
struct timer_list hello_timer;
@ -483,11 +501,27 @@ static inline bool br_multicast_is_router(struct net_bridge *br)
timer_pending(&br->multicast_router_timer));
}
static inline bool br_multicast_querier_exists(struct net_bridge *br)
static inline bool
__br_multicast_querier_exists(struct net_bridge *br,
struct bridge_mcast_querier *querier)
{
return time_is_before_jiffies(br->multicast_querier_delay_time) &&
(br->multicast_querier ||
timer_pending(&br->multicast_querier_timer));
return time_is_before_jiffies(querier->delay_time) &&
(br->multicast_querier || timer_pending(&querier->timer));
}
static inline bool br_multicast_querier_exists(struct net_bridge *br,
struct ethhdr *eth)
{
switch (eth->h_proto) {
case (htons(ETH_P_IP)):
return __br_multicast_querier_exists(br, &br->ip4_querier);
#if IS_ENABLED(CONFIG_IPV6)
case (htons(ETH_P_IPV6)):
return __br_multicast_querier_exists(br, &br->ip6_querier);
#endif
default:
return false;
}
}
#else
static inline int br_multicast_rcv(struct net_bridge *br,
@ -545,7 +579,8 @@ static inline bool br_multicast_is_router(struct net_bridge *br)
{
return 0;
}
static inline bool br_multicast_querier_exists(struct net_bridge *br)
static inline bool br_multicast_querier_exists(struct net_bridge *br,
struct ethhdr *eth)
{
return false;
}