* Re: [PATCH] virtio-net: Set RXCSUM feature if GUEST_CSUM is available
From: Rusty Russell @ 2013-09-02 1:47 UTC (permalink / raw)
To: David Miller, thuth; +Cc: netdev, mst, virtualization
In-Reply-To: <20130829.155704.248095796202059854.davem@davemloft.net>
David Miller <davem@davemloft.net> writes:
> From: Thomas Huth <thuth@linux.vnet.ibm.com>
> Date: Tue, 27 Aug 2013 17:09:02 +0200
>
>> If the VIRTIO_NET_F_GUEST_CSUM virtio feature is available, the guest
>> does not have to calculate the checksums on all received packets. This
>> is pretty much the same feature as RX checksum offloading on real
>> network cards, so the virtio-net driver should report this by setting
>> the NETIF_F_RXCSUM flag. When the user now runs "ethtool -k", he or she
>> can see whether the virtio-net interface has to calculate RX checksums
>> or not.
>>
>> Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
>
> Can one of the virtio_net folks please review this?
Hmm, so NETIF_F_RXCSUM only exists for ethtool's benefit. Weird.
But this patch is correct:
Acked-by: Rusty Russell <rusty@rustcorp.com.au>
Thanks,
Rusty.
^ permalink raw reply
* RE: [PATCH] net: fec: fix the error to get the previous BD entry
From: Duan Fugang-B38611 @ 2013-09-02 1:37 UTC (permalink / raw)
To: David Miller
Cc: Li Frank-B20596, netdev@vger.kernel.org,
bhutchings@solarflare.com, l.stach@pengutronix.de
In-Reply-To: <20130830.175909.1743525148095642605.davem@davemloft.net>
From: David Miller <davem@davemloft.net>
Data: Saturday, August 31, 2013 5:59 AM
> To: Duan Fugang-B38611
> Cc: Li Frank-B20596; netdev@vger.kernel.org; bhutchings@solarflare.com;
> l.stach@pengutronix.de
> Subject: Re: [PATCH] net: fec: fix the error to get the previous BD entry
>
> From: Fugang Duan <B38611@freescale.com>
> Date: Fri, 30 Aug 2013 12:35:25 +0800
>
> > When the current BD is the first BD, the previous BD entry must be the
> > last BD, not "bdp - 1".
> >
> > Add BD entry check to get the previous BD entry correctly.
> >
> > Signed-off-by: Fugang Duan <B38611@freescale.com>
>
> The correct fix is to put this logic into fec_enet_get_prevdesc().
> With this current limitation, the function is completely useless.
Due to get tx & rx previous description use the same function fec_enet_get_prevdesc(). If put the logic into fec_enet_get_prevdesc(),
I think it is better to split the function to fec_enet_get_tx_prevdesc(),fec_enet_get_rx_prevdesc().
If you agree it, I will submit one patch to do it.
Thanks,
Andy
^ permalink raw reply
* Re: [PATCH net-next v12 06/11] vxlan: add ipv6 support
From: Cong Wang @ 2013-09-02 1:17 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev, David S. Miller, David Stevens
In-Reply-To: <20130831102726.21896150@nehalam.linuxnetplumber.net>
On Sat, 2013-08-31 at 10:27 -0700, Stephen Hemminger wrote:
> On Sat, 31 Aug 2013 13:44:33 +0800
> Cong Wang <amwang@redhat.com> wrote:
>
> > +#if IS_ENABLED(CONFIG_IPV6)
> > + } else {
> > + ipv6_stub->ipv6_sock_mc_join(sk, ifindex,
> > + &ip->sin6.sin6_addr);
> > +#endif
>
> This isn't safe against IPv6 module getting unloaded. You either
> have to figure out a reference count method, or disable IPv6
> module unload.
>
> Since it can only be forced unload anyway, I still argue
> it should just be disabled (by removing the module exit hook
> and code).
I will send a patch to remove ipv6 module exit code, since there is
other problem too.
Thanks!
^ permalink raw reply
* [PATCH] net: netx-eth: remove unnecessary casting when using dev_get_platdata()
From: Jingoo Han @ 2013-09-02 0:37 UTC (permalink / raw)
To: 'David S. Miller'
Cc: netdev, 'Sergei Shtylyov', 'Jingoo Han'
Casting from 'void *' is unnecessary when using dev_get_platdata().
Reported-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
drivers/net/ethernet/netx-eth.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/netx-eth.c b/drivers/net/ethernet/netx-eth.c
index 235fd51..e6f0a43 100644
--- a/drivers/net/ethernet/netx-eth.c
+++ b/drivers/net/ethernet/netx-eth.c
@@ -390,7 +390,7 @@ static int netx_eth_drv_probe(struct platform_device *pdev)
priv = netdev_priv(ndev);
- pdata = (struct netxeth_platform_data *)dev_get_platdata(&pdev->dev);
+ pdata = dev_get_platdata(&pdev->dev);
priv->xc = request_xc(pdata->xcno, &pdev->dev);
if (!priv->xc) {
dev_err(&pdev->dev, "unable to request xc engine\n");
--
1.7.10.4
^ permalink raw reply related
* [PATCH net-hext] wireless: scan: Remove comment to compare_ether_addr
From: Joe Perches @ 2013-09-01 22:48 UTC (permalink / raw)
To: Johannes Berg
Cc: John W. Linville, David S. Miller, linux-wireless, netdev, LKML
This function is being removed, so remove the reference to it.
Signed-off-by: Joe Perches <joe@perches.com>
---
net/wireless/scan.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index ad1e406..eeb7148 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -465,10 +465,6 @@ static int cmp_bss(struct cfg80211_bss *a,
}
}
- /*
- * we can't use compare_ether_addr here since we need a < > operator.
- * The binary return value of compare_ether_addr isn't enough
- */
r = memcmp(a->bssid, b->bssid, sizeof(a->bssid));
if (r)
return r;
^ permalink raw reply related
* [PATCH] batman: Remove reference to compare_ether_addr
From: Joe Perches @ 2013-09-01 22:45 UTC (permalink / raw)
To: Marek Lindner, Simon Wunderlich, Antonio Quartulli
Cc: David S. Miller, b.a.t.m.a.n, netdev, LKML
This function is being removed, rename the reference.
Signed-off-by: Joe Perches <joe@perches.com>
---
net/batman-adv/main.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h
index 5e9aebb..7333cf8 100644
--- a/net/batman-adv/main.h
+++ b/net/batman-adv/main.h
@@ -253,7 +253,7 @@ static inline void batadv_dbg(int type __always_unused,
/* returns 1 if they are the same ethernet addr
*
- * note: can't use compare_ether_addr() as it requires aligned memory
+ * note: can't use ether_addr_equal() as it requires aligned memory
*/
static inline int batadv_compare_eth(const void *data1, const void *data2)
{
^ permalink raw reply related
* Re: Realtek r8168 hangs when sending data at full speed on a gigabit link
From: Francois Romieu @ 2013-09-01 21:36 UTC (permalink / raw)
To: Frédéric Leroy; +Cc: netdev, Realtek linux nic maintainers
In-Reply-To: <5221C226.9040209@starox.org>
Frédéric Leroy <fredo@starox.org> :
[...]
> For triggering the bug, I use iperf, which either works, or hangs almost
> immediately
> with multiple threads :
>
> iperf -c myiperfserver -P 3 -t 60
>
> Could you help me to fix this ?
Does it behave the same if you don't load the vbox modules at all ?
--
Ueimor
^ permalink raw reply
* [PATCH net-next] bcm87xx: Add MODULE_DEVICE_TABLE
From: Ben Hutchings @ 2013-09-01 21:33 UTC (permalink / raw)
To: David Miller; +Cc: David Daney, netdev
[-- Attachment #1: Type: text/plain, Size: 705 bytes --]
bcm87xx currently isn't auto-loaded if built as a module.
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
Compile-tested only.
Ben.
drivers/net/phy/bcm87xx.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/net/phy/bcm87xx.c b/drivers/net/phy/bcm87xx.c
index 7997895..f5b44ff 100644
--- a/drivers/net/phy/bcm87xx.c
+++ b/drivers/net/phy/bcm87xx.c
@@ -230,4 +230,11 @@ static void __exit bcm87xx_exit(void)
}
module_exit(bcm87xx_exit);
+static struct mdio_device_id __maybe_unused bcm87xx_tbl[] = {
+ { PHY_ID_BCM8706, 0xffffffff },
+ { PHY_ID_BCM8727, 0xffffffff },
+ { }
+};
+
MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(mdio, bcm87xx_tbl);
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]
^ permalink raw reply related
* Re: [PATCH v3] ipv6:introduce function to find route for redirect
From: Hannes Frederic Sowa @ 2013-09-01 21:08 UTC (permalink / raw)
To: Duan Jiong; +Cc: davem, netdev
In-Reply-To: <52217A8D.9010008@cn.fujitsu.com>
On Sat, Aug 31, 2013 at 01:09:33PM +0800, Duan Jiong wrote:
> RFC 4861 says that the IP source address of the Redirect is the
> same as the current first-hop router for the specified ICMP
> Destination Address, so the gateway should be taken into
> consideration when we find the route for redirect.
>
> Signed-off-by: Duan Jiong <duanj.fnst@cn.fujitsu.com>
This patch looks good!
Maybe you could also point to commit
a6279458c534d01ccc39498aba61c93083ee0372 ("NDISC: Search over all possible
rules on receipt of redirect.") and where the check went away?
The bug is only "exploitable" on layer-2 because the source address of the
redirect is checked to be a valid link-local address but it makes spoofing a
lot easier in the same L2 domain nonetheless.
Nice work!
Some smaller comments inline:
> ---
> Changes for v3:
> 1.Fix the comments style problems
>
> net/ipv6/ah6.c | 2 +-
> net/ipv6/esp6.c | 2 +-
> net/ipv6/icmp.c | 2 +-
> net/ipv6/ipcomp6.c | 2 +-
> net/ipv6/ndisc.c | 3 ++-
> net/ipv6/route.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++-----
> 6 files changed, 78 insertions(+), 11 deletions(-)
>
> diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
> index bb02e17..73784c3 100644
> --- a/net/ipv6/ah6.c
> +++ b/net/ipv6/ah6.c
> @@ -628,7 +628,7 @@ static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
> return;
>
> if (type == NDISC_REDIRECT)
> - ip6_redirect(skb, net, 0, 0);
> + ip6_redirect(skb, net, skb->dev->ifindex, 0);
> else
> ip6_update_pmtu(skb, net, info, 0, 0);
> xfrm_state_put(x);
> diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
> index aeac0dc..d3618a7 100644
> --- a/net/ipv6/esp6.c
> +++ b/net/ipv6/esp6.c
> @@ -447,7 +447,7 @@ static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
> return;
>
> if (type == NDISC_REDIRECT)
> - ip6_redirect(skb, net, 0, 0);
> + ip6_redirect(skb, net, skb->dev->ifindex, 0);
> else
> ip6_update_pmtu(skb, net, info, 0, 0);
> xfrm_state_put(x);
> diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
> index 7cfc8d2..73681c2 100644
> --- a/net/ipv6/icmp.c
> +++ b/net/ipv6/icmp.c
> @@ -92,7 +92,7 @@ static void icmpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
> if (type == ICMPV6_PKT_TOOBIG)
> ip6_update_pmtu(skb, net, info, 0, 0);
> else if (type == NDISC_REDIRECT)
> - ip6_redirect(skb, net, 0, 0);
> + ip6_redirect(skb, net, skb->dev->ifindex, 0);
>
> if (!(type & ICMPV6_INFOMSG_MASK))
> if (icmp6->icmp6_type == ICMPV6_ECHO_REQUEST)
> diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
> index 7af5aee..5636a91 100644
> --- a/net/ipv6/ipcomp6.c
> +++ b/net/ipv6/ipcomp6.c
> @@ -76,7 +76,7 @@ static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
> return;
>
> if (type == NDISC_REDIRECT)
> - ip6_redirect(skb, net, 0, 0);
> + ip6_redirect(skb, net, skb->dev->ifindex, 0);
> else
> ip6_update_pmtu(skb, net, info, 0, 0);
> xfrm_state_put(x);
> diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
> index 04d31c2..90f474b 100644
> --- a/net/ipv6/ndisc.c
> +++ b/net/ipv6/ndisc.c
> @@ -1370,7 +1370,8 @@ static void ndisc_redirect_rcv(struct sk_buff *skb)
> return;
>
> if (!ndopts.nd_opts_rh) {
> - ip6_redirect_no_header(skb, dev_net(skb->dev), 0, 0);
> + ip6_redirect_no_header(skb, dev_net(skb->dev),
> + skb->dev->ifindex, 0);
This is not indented correctly. skb->dev->ifindex should be placed right below
the upper skb variable.
> return;
> }
>
> diff --git a/net/ipv6/route.c b/net/ipv6/route.c
> index 8d9a93e..2e1d378 100644
> --- a/net/ipv6/route.c
> +++ b/net/ipv6/route.c
> @@ -1157,6 +1157,74 @@ void ip6_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, __be32 mtu)
> }
> EXPORT_SYMBOL_GPL(ip6_sk_update_pmtu);
>
> +/* Handle redirects */
> +struct ip6rd_flowi {
> + struct flowi6 fl6;
> + struct in6_addr gateway;
> +};
> +
> +static struct rt6_info *__ip6_route_redirect(struct net *net,
> + struct fib6_table *table,
> + struct flowi6 *fl6,
> + int flags)
> +{
> + struct ip6rd_flowi *rdfl = (struct ip6rd_flowi *)fl6;
> + struct rt6_info *rt;
> + struct fib6_node *fn;
> +
> + /* Get the "current" route for this destination and
> + * check if the redirect has come from approriate router.
> + *
> + * RFC 4861 specifies that redirects should only be
> + * accepted if they come from the nexthop to the target.
> + * Due to the way the routes are chosen, this notion
> + * is a bit fuzzy and one might need to check all possible
> + * routes.
> + */
> +
> + read_lock_bh(&table->tb6_lock);
> + fn = fib6_lookup(&table->tb6_root, &fl6->daddr, &fl6->saddr);
> +restart:
> + for (rt = fn->leaf; rt; rt = rt->dst.rt6_next) {
> + if (rt6_check_expired(rt))
> + continue;
[1] (backreference for a comment below)
> + if (!(rt->rt6i_flags & RTF_GATEWAY))
> + continue;
> + if (fl6->flowi6_oif != rt->dst.dev->ifindex)
> + continue;
> + if (!ipv6_addr_equal(&rdfl->gateway, &rt->rt6i_gateway))
> + continue;
> + break;
> + }
> +
> + if (!rt)
> + rt = net->ipv6.ip6_null_entry;
> + BACKTRACK(net, &fl6->saddr);
> +out:
> + dst_hold(&rt->dst);
> +
> + read_unlock_bh(&table->tb6_lock);
> +
> + return rt;
> +};
> +
> +static struct dst_entry *ip6_route_redirect(const struct flowi6 *fl6,
> + const struct in6_addr *gateway,
> + struct net *net)
The ordering of the arguments could be in the same style as the other
ip6_route_* functions (net, flow, gateway). But that is not that important.
> +{
> + int flags = RT6_LOOKUP_F_HAS_SADDR;
> + struct ip6rd_flowi rdfl;
> +
> + rdfl.fl6 = *fl6;
> + rdfl.gateway = *gateway;
> +
> + if (rt6_need_strict(&fl6->daddr))
> + flags |= RT6_LOOKUP_F_IFACE;
This is not needed because you do the matching on interfaces yourself
in __ip6_route_redirect. The flag should currently not be checked on
this code path down in fib6_rule_lookup.
> +
> + return fib6_rule_lookup(net, &rdfl.fl6,
> + flags, __ip6_route_redirect);
This line jumped a bit too far to the right, too. ;)
> +}
> +
> void ip6_redirect(struct sk_buff *skb, struct net *net, int oif, u32 mark)
Maybe we should rename oif to iif now?
> {
> const struct ipv6hdr *iph = (struct ipv6hdr *) skb->data;
> @@ -1171,9 +1239,8 @@ void ip6_redirect(struct sk_buff *skb, struct net *net, int oif, u32 mark)
> fl6.saddr = iph->saddr;
> fl6.flowlabel = ip6_flowinfo(iph);
>
> - dst = ip6_route_output(net, NULL, &fl6);
> - if (!dst->error)
> - rt6_do_redirect(dst, NULL, skb);
> + dst = ip6_route_redirect(&fl6, &ipv6_hdr(skb)->saddr, net);
> + rt6_do_redirect(dst, NULL, skb);
What is the reason you left out the dst.error check? E.g. if a system had a
prohbit rule it is possible to circumvent this with a redirect packet now.
I would think about placing this check at [1] and fail the lookup
early. rt6_do_redirect does check for null-entry, so you could omit the
check here, then.
> dst_release(dst);
> }
> EXPORT_SYMBOL_GPL(ip6_redirect);
> @@ -1193,9 +1260,8 @@ void ip6_redirect_no_header(struct sk_buff *skb, struct net *net, int oif,
> fl6.daddr = msg->dest;
> fl6.saddr = iph->daddr;
>
> - dst = ip6_route_output(net, NULL, &fl6);
> - if (!dst->error)
> - rt6_do_redirect(dst, NULL, skb);
> + dst = ip6_route_redirect(&fl6, &iph->saddr, net);
> + rt6_do_redirect(dst, NULL, skb);
Likewise.
> dst_release(dst);
> }
Thanks,
Hannes
^ permalink raw reply
* [PATCH net-next] llc: Use normal etherdevice.h tests
From: Joe Perches @ 2013-09-01 20:11 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo; +Cc: David Miller, netdev, LKML
Convert the llc_<foo> static inlines to the
equivalents from etherdevice.h and remove
the llc_<foo> static inline functions.
llc_mac_null -> is_zero_ether_addr
llc_mac_multicast -> is_multicast_ether_addr
llc_mac_match -> ether_addr_equal
Signed-off-by: Joe Perches <joe@perches.com>
---
include/net/llc_if.h | 30 ------------------------------
net/llc/af_llc.c | 6 +++---
net/llc/llc_conn.c | 6 +++---
net/llc/llc_sap.c | 4 ++--
4 files changed, 8 insertions(+), 38 deletions(-)
diff --git a/include/net/llc_if.h b/include/net/llc_if.h
index b595a00..f0cb909 100644
--- a/include/net/llc_if.h
+++ b/include/net/llc_if.h
@@ -62,36 +62,6 @@
#define LLC_STATUS_CONFLICT 7 /* disconnect conn */
#define LLC_STATUS_RESET_DONE 8 /* */
-/**
- * llc_mac_null - determines if a address is a null mac address
- * @mac: Mac address to test if null.
- *
- * Determines if a given address is a null mac address. Returns 0 if the
- * address is not a null mac, 1 if the address is a null mac.
- */
-static inline int llc_mac_null(const u8 *mac)
-{
- return is_zero_ether_addr(mac);
-}
-
-static inline int llc_mac_multicast(const u8 *mac)
-{
- return is_multicast_ether_addr(mac);
-}
-/**
- * llc_mac_match - determines if two mac addresses are the same
- * @mac1: First mac address to compare.
- * @mac2: Second mac address to compare.
- *
- * Determines if two given mac address are the same. Returns 0 if there
- * is not a complete match up to len, 1 if a complete match up to len is
- * found.
- */
-static inline int llc_mac_match(const u8 *mac1, const u8 *mac2)
-{
- return !compare_ether_addr(mac1, mac2);
-}
-
extern int llc_establish_connection(struct sock *sk, u8 *lmac,
u8 *dmac, u8 dsap);
extern int llc_build_and_send_pkt(struct sock *sk, struct sk_buff *skb);
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index 48aaa89..6cba486 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -321,12 +321,12 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
if (llc->dev) {
if (!addr->sllc_arphrd)
addr->sllc_arphrd = llc->dev->type;
- if (llc_mac_null(addr->sllc_mac))
+ if (is_zero_ether_addr(addr->sllc_mac))
memcpy(addr->sllc_mac, llc->dev->dev_addr,
IFHWADDRLEN);
if (addr->sllc_arphrd != llc->dev->type ||
- !llc_mac_match(addr->sllc_mac,
- llc->dev->dev_addr)) {
+ !ether_addr_equal(addr->sllc_mac,
+ llc->dev->dev_addr)) {
rc = -EINVAL;
llc->dev = NULL;
}
diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c
index 0d0d416..cd87241 100644
--- a/net/llc/llc_conn.c
+++ b/net/llc/llc_conn.c
@@ -478,8 +478,8 @@ static inline bool llc_estab_match(const struct llc_sap *sap,
return llc->laddr.lsap == laddr->lsap &&
llc->daddr.lsap == daddr->lsap &&
- llc_mac_match(llc->laddr.mac, laddr->mac) &&
- llc_mac_match(llc->daddr.mac, daddr->mac);
+ ether_addr_equal(llc->laddr.mac, laddr->mac) &&
+ ether_addr_equal(llc->daddr.mac, daddr->mac);
}
/**
@@ -550,7 +550,7 @@ static inline bool llc_listener_match(const struct llc_sap *sap,
return sk->sk_type == SOCK_STREAM && sk->sk_state == TCP_LISTEN &&
llc->laddr.lsap == laddr->lsap &&
- llc_mac_match(llc->laddr.mac, laddr->mac);
+ ether_addr_equal(llc->laddr.mac, laddr->mac);
}
static struct sock *__llc_lookup_listener(struct llc_sap *sap,
diff --git a/net/llc/llc_sap.c b/net/llc/llc_sap.c
index 78be45c..e585069 100644
--- a/net/llc/llc_sap.c
+++ b/net/llc/llc_sap.c
@@ -302,7 +302,7 @@ static inline bool llc_dgram_match(const struct llc_sap *sap,
return sk->sk_type == SOCK_DGRAM &&
llc->laddr.lsap == laddr->lsap &&
- llc_mac_match(llc->laddr.mac, laddr->mac);
+ ether_addr_equal(llc->laddr.mac, laddr->mac);
}
/**
@@ -425,7 +425,7 @@ void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb)
llc_pdu_decode_da(skb, laddr.mac);
llc_pdu_decode_dsap(skb, &laddr.lsap);
- if (llc_mac_multicast(laddr.mac)) {
+ if (is_multicast_ether_addr(laddr.mac)) {
llc_sap_mcast(sap, &laddr, skb);
kfree_skb(skb);
} else {
^ permalink raw reply related
* WLAN setting "Power Management:on" lost after suspend
From: Toralf Förster @ 2013-09-01 20:01 UTC (permalink / raw)
To: netdev
After an s2disk I've to run "iwconfig wlp3s0 power on" again at a
ThinkPad T420 although I did it before suspend.
(kernel 3.11-rc7+, but older kernels shows same behaviour)
Is this intended ?
--
MfG/Sincerely
Toralf Förster
pgp finger print: 7B1A 07F4 EC82 0F90 D4C2 8936 872A E508 7DB6 9DA3
^ permalink raw reply
* [PATCH 2/2] tcp: syncookies: reduce mss table to four values
From: Florian Westphal @ 2013-09-01 19:55 UTC (permalink / raw)
To: netdev; +Cc: Florian Westphal
In-Reply-To: <1378065356-25509-1-git-send-email-fw@strlen.de>
Halve mss table size to make blind cookie guessing more difficult.
This is sad since the tables were already small, but there
is little alternative except perhaps adding more precise mss information
in the tcp timestamp. Timestamps are unfortunately not ubiquitous.
Guessing all possible cookie values still has 8-in 2**32 chance.
Reported-by: Jakob Lell <jakob@jakoblell.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
Changes since v1:
- add comment explaining mss choices
net/ipv4/syncookies.c | 23 ++++++++++++-----------
net/ipv6/syncookies.c | 6 +-----
2 files changed, 13 insertions(+), 16 deletions(-)
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index b6ea297..b47f477 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -136,22 +136,23 @@ static __u32 check_tcp_syn_cookie(__u32 cookie, __be32 saddr, __be32 daddr,
}
/*
- * MSS Values are taken from the 2009 paper
- * 'Measuring TCP Maximum Segment Size' by S. Alcock and R. Nelson:
- * - values 1440 to 1460 accounted for 80% of observed mss values
- * - values outside the 536-1460 range are rare (<0.2%).
+ * MSS Values are chosen based on the 2011 paper
+ * 'An Analysis of TCP Maximum Segement Sizes' by S. Alcock and R. Nelson: Values ...
+ * .. lower than 536 are rare (< 0.2%)
+ * .. between 537 and 1299 account for less than < 1.5% of observed values
+ * .. in the 1300-1349 range account for about 15 to 20% of observed mss values
+ * .. exceeding 1460 are very rare (< 0.04%)
+ *
+ * 1460 is the single most frequently announced mss value (30 to 46% depending
+ * on monitor location)
*
* Table must be sorted.
*/
static __u16 const msstab[] = {
- 64,
- 512,
- 536,
- 1024,
- 1440,
+ 536,
+ 1300,
+ 1440, /* 1440, 1452: PPPoE */
1460,
- 4312,
- 8960,
};
/*
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
index 13ca0a0..7198640 100644
--- a/net/ipv6/syncookies.c
+++ b/net/ipv6/syncookies.c
@@ -26,13 +26,9 @@
/* Table must be sorted. */
static __u16 const msstab[] = {
- 64,
- 512,
- 536,
- 1280 - 60,
+ 1280 - 60, /* IPV6_MIN_MTU - 60 */
1480 - 60,
1500 - 60,
- 4460 - 60,
9000 - 60,
};
--
1.8.1.5
^ permalink raw reply related
* [PATCH v2 -next 1/2] tcp: syncookies: reduce cookie lifetime to 128 seconds
From: Florian Westphal @ 2013-09-01 19:55 UTC (permalink / raw)
To: netdev; +Cc: Florian Westphal
We currently accept cookies that were created less than 4 minutes ago
(ie, cookies with counter delta 0-3). Combined with the 8 mss table
values, this yields 32 possible values (out of 2**32) that will be valid.
Reducing the lifetime to < 2 minutes halves the guessing chance while
still providing a large enough period.
While at it, get rid of jiffies value -- they overflow too quickly on
32 bit platforms.
getnstimeofday is used to create a counter that increments every 64s.
perf shows getnstimeofday cost is negible compared to sha_transform;
'ordinary' sequence number generation uses getnstimeofday, too.
Reported-by: Jakob Lell <jakob@jakoblell.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
Changes since v1:
- add comment explaining MAX_SYNCOOKIE_AGE value
- add sentence about 'getnstimeofday' cost to commit message
- rebase on net-next master
include/net/tcp.h | 19 +++++++++++++++++++
net/ipv4/syncookies.c | 31 ++++++++++---------------------
net/ipv6/syncookies.c | 24 +++++++-----------------
3 files changed, 35 insertions(+), 38 deletions(-)
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 6a6a88d..7d9205c 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -482,6 +482,24 @@ extern int __cookie_v4_check(const struct iphdr *iph, const struct tcphdr *th,
extern struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
struct ip_options *opt);
#ifdef CONFIG_SYN_COOKIES
+#include <linux/ktime.h>
+
+/* Syncookies use a monotonic timer which increments every 64 seconds.
+ * This counter is used both as a hash input and partially encoded into
+ * the cookie value. A cookie is only validated further if the delta
+ * between the current counter value and the encoded one is less than this,
+ * i.e. a sent cookie is valid only at most for 128 seconds (or less if
+ * the counter advances immediately after a cookie is generated).
+ */
+#define MAX_SYNCOOKIE_AGE 2
+
+static inline u32 tcp_cookie_time(void)
+{
+ struct timespec now;
+ getnstimeofday(&now);
+ return now.tv_sec >> 6; /* 64 seconds granularity */
+}
+
extern u32 __cookie_v4_init_sequence(const struct iphdr *iph,
const struct tcphdr *th, u16 *mssp);
extern __u32 cookie_v4_init_sequence(struct sock *sk, struct sk_buff *skb,
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index 14a15c4..b6ea297 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -89,8 +89,7 @@ __u32 cookie_init_timestamp(struct request_sock *req)
static __u32 secure_tcp_syn_cookie(__be32 saddr, __be32 daddr, __be16 sport,
- __be16 dport, __u32 sseq, __u32 count,
- __u32 data)
+ __be16 dport, __u32 sseq, __u32 data)
{
/*
* Compute the secure sequence number.
@@ -102,7 +101,7 @@ static __u32 secure_tcp_syn_cookie(__be32 saddr, __be32 daddr, __be16 sport,
* As an extra hack, we add a small "data" value that encodes the
* MSS into the second hash value.
*/
-
+ u32 count = tcp_cookie_time();
return (cookie_hash(saddr, daddr, sport, dport, 0, 0) +
sseq + (count << COOKIEBITS) +
((cookie_hash(saddr, daddr, sport, dport, count, 1) + data)
@@ -114,22 +113,21 @@ static __u32 secure_tcp_syn_cookie(__be32 saddr, __be32 daddr, __be16 sport,
* If the syncookie is bad, the data returned will be out of
* range. This must be checked by the caller.
*
- * The count value used to generate the cookie must be within
- * "maxdiff" if the current (passed-in) "count". The return value
- * is (__u32)-1 if this test fails.
+ * The count value used to generate the cookie must be less than
+ * MAX_SYNCOOKIE_AGE minutes in the past.
+ * The return value (__u32)-1 if this test fails.
*/
static __u32 check_tcp_syn_cookie(__u32 cookie, __be32 saddr, __be32 daddr,
- __be16 sport, __be16 dport, __u32 sseq,
- __u32 count, __u32 maxdiff)
+ __be16 sport, __be16 dport, __u32 sseq)
{
- __u32 diff;
+ u32 diff, count = tcp_cookie_time();
/* Strip away the layers from the cookie */
cookie -= cookie_hash(saddr, daddr, sport, dport, 0, 0) + sseq;
/* Cookie is now reduced to (count * 2^24) ^ (hash % 2^24) */
diff = (count - (cookie >> COOKIEBITS)) & ((__u32) - 1 >> COOKIEBITS);
- if (diff >= maxdiff)
+ if (diff >= MAX_SYNCOOKIE_AGE)
return (__u32)-1;
return (cookie -
@@ -173,7 +171,7 @@ u32 __cookie_v4_init_sequence(const struct iphdr *iph, const struct tcphdr *th,
return secure_tcp_syn_cookie(iph->saddr, iph->daddr,
th->source, th->dest, ntohl(th->seq),
- jiffies / (HZ * 60), mssind);
+ mssind);
}
EXPORT_SYMBOL_GPL(__cookie_v4_init_sequence);
@@ -189,13 +187,6 @@ __u32 cookie_v4_init_sequence(struct sock *sk, struct sk_buff *skb, __u16 *mssp)
}
/*
- * This (misnamed) value is the age of syncookie which is permitted.
- * Its ideal value should be dependent on TCP_TIMEOUT_INIT and
- * sysctl_tcp_retries1. It's a rather complicated formula (exponential
- * backoff) to compute at runtime so it's currently hardcoded here.
- */
-#define COUNTER_TRIES 4
-/*
* Check if a ack sequence number is a valid syncookie.
* Return the decoded mss if it is, or 0 if not.
*/
@@ -204,9 +195,7 @@ int __cookie_v4_check(const struct iphdr *iph, const struct tcphdr *th,
{
__u32 seq = ntohl(th->seq) - 1;
__u32 mssind = check_tcp_syn_cookie(cookie, iph->saddr, iph->daddr,
- th->source, th->dest, seq,
- jiffies / (HZ * 60),
- COUNTER_TRIES);
+ th->source, th->dest, seq);
return mssind < ARRAY_SIZE(msstab) ? msstab[mssind] : 0;
}
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
index bf63ac8..13ca0a0 100644
--- a/net/ipv6/syncookies.c
+++ b/net/ipv6/syncookies.c
@@ -36,14 +36,6 @@ static __u16 const msstab[] = {
9000 - 60,
};
-/*
- * This (misnamed) value is the age of syncookie which is permitted.
- * Its ideal value should be dependent on TCP_TIMEOUT_INIT and
- * sysctl_tcp_retries1. It's a rather complicated formula (exponential
- * backoff) to compute at runtime so it's currently hardcoded here.
- */
-#define COUNTER_TRIES 4
-
static inline struct sock *get_cookie_sock(struct sock *sk, struct sk_buff *skb,
struct request_sock *req,
struct dst_entry *dst)
@@ -86,8 +78,9 @@ static u32 cookie_hash(const struct in6_addr *saddr, const struct in6_addr *dadd
static __u32 secure_tcp_syn_cookie(const struct in6_addr *saddr,
const struct in6_addr *daddr,
__be16 sport, __be16 dport, __u32 sseq,
- __u32 count, __u32 data)
+ __u32 data)
{
+ u32 count = tcp_cookie_time();
return (cookie_hash(saddr, daddr, sport, dport, 0, 0) +
sseq + (count << COOKIEBITS) +
((cookie_hash(saddr, daddr, sport, dport, count, 1) + data)
@@ -96,15 +89,14 @@ static __u32 secure_tcp_syn_cookie(const struct in6_addr *saddr,
static __u32 check_tcp_syn_cookie(__u32 cookie, const struct in6_addr *saddr,
const struct in6_addr *daddr, __be16 sport,
- __be16 dport, __u32 sseq, __u32 count,
- __u32 maxdiff)
+ __be16 dport, __u32 sseq)
{
- __u32 diff;
+ __u32 diff, count = tcp_cookie_time();
cookie -= cookie_hash(saddr, daddr, sport, dport, 0, 0) + sseq;
diff = (count - (cookie >> COOKIEBITS)) & ((__u32) -1 >> COOKIEBITS);
- if (diff >= maxdiff)
+ if (diff >= MAX_SYNCOOKIE_AGE)
return (__u32)-1;
return (cookie -
@@ -125,8 +117,7 @@ u32 __cookie_v6_init_sequence(const struct ipv6hdr *iph,
*mssp = msstab[mssind];
return secure_tcp_syn_cookie(&iph->saddr, &iph->daddr, th->source,
- th->dest, ntohl(th->seq),
- jiffies / (HZ * 60), mssind);
+ th->dest, ntohl(th->seq), mssind);
}
EXPORT_SYMBOL_GPL(__cookie_v6_init_sequence);
@@ -146,8 +137,7 @@ int __cookie_v6_check(const struct ipv6hdr *iph, const struct tcphdr *th,
{
__u32 seq = ntohl(th->seq) - 1;
__u32 mssind = check_tcp_syn_cookie(cookie, &iph->saddr, &iph->daddr,
- th->source, th->dest, seq,
- jiffies / (HZ * 60), COUNTER_TRIES);
+ th->source, th->dest, seq);
return mssind < ARRAY_SIZE(msstab) ? msstab[mssind] : 0;
}
--
1.8.1.5
^ permalink raw reply related
* [PATCH] Fix for loading non-namespace aware ipv4 protocols without CONFIG_NAMESPACES
From: Paul Wouters @ 2013-09-01 19:30 UTC (permalink / raw)
To: James Morris, David S. Miller; +Cc: netdev
[-- Attachment #1: Type: text/plain, Size: 433 bytes --]
Attached is a trivial patch to allow inet_add_protocol on kernels without CONFIG_NAMESPACES to load non-namespace aware (out of kernel) modules.
For IPv6, there is no such check. Some discussion of that can be found in the archive: http://www.spinics.net/lists/netdev/msg225184.html
I'm ambivalent on whether the check should be there (like in ipv4) or not (like in ipv6). But if it is there, it should use the proper #ifdef.
Paul
[-- Attachment #2: ipv4-protocol-nonamespace.patch --]
[-- Type: text/x-patch, Size: 841 bytes --]
commit 9e3ddb21568284fb9061a91bbd3158909b1dec45
Author: Paul Wouters <pwouters@redhat.com>
Date: Sun Sep 1 15:18:37 2013 -0400
* Fix for loading non-namespace aware ipv4 protocols without
CONFIG_NAMESPACES set. IPv6 does not have this check.
diff --git a/net/ipv4/protocol.c b/net/ipv4/protocol.c
index ce84846..b5f785c 100644
--- a/net/ipv4/protocol.c
+++ b/net/ipv4/protocol.c
@@ -37,11 +37,13 @@ const struct net_offload __rcu *inet_offloads[MAX_INET_PROTOS] __read_mostly;
int inet_add_protocol(const struct net_protocol *prot, unsigned char protocol)
{
+#ifdef CONFIG_NAMESPACES
if (!prot->netns_ok) {
pr_err("Protocol %u is not namespace aware, cannot register.\n",
protocol);
return -EINVAL;
}
+#endif
return !cmpxchg((const struct net_protocol **)&inet_protos[protocol],
NULL, prot) ? 0 : -1;
^ permalink raw reply related
* Re: ICMPv6: treat dest unreachable codes 5 and 6 as EACCES, not EPROTO
From: Hannes Frederic Sowa @ 2013-09-01 18:54 UTC (permalink / raw)
To: Jiri Bohac; +Cc: Hideaki YOSHIFUJI, David S. Miller, netdev
In-Reply-To: <20130830091844.GA2706@midget.suse.cz>
On Fri, Aug 30, 2013 at 11:18:45AM +0200, Jiri Bohac wrote:
> RFC 4443 has defined two additional codes for ICMPv6 type 1 (destination
> unreachable) messages:
> 5 - Source address failed ingress/egress policy
> 6 - Reject route to destination
>
> Now they are treated as protocol error and icmpv6_err_convert() converts them
> to EPROTO.
>
> RFC 4443 says:
> "Codes 5 and 6 are more informative subsets of code 1."
>
> Treat codes 5 and 6 as code 1 (EACCES)
>
> Btw, connect() returning -EPROTO confuses firefox, so that fallback to
> other/IPv4 addresses does not work:
> https://bugzilla.mozilla.org/show_bug.cgi?id=910773
>
>
> Signed-off-by: Jiri Bohac <jbohac@suse.cz>
I would also propose it for stable.
Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Thanks,
Hannes
^ permalink raw reply
* [PATCH net-next] drivers/net: Convert uses of compare_ether_addr to ether_addr_equal
From: Joe Perches @ 2013-09-01 18:51 UTC (permalink / raw)
To: netdev; +Cc: e1000-devel, linux-wireless, linux-kernel, users
Use the new bool function ether_addr_equal to add
some clarity and reduce the likelihood for misuse
of compare_ether_addr for sorting.
Done via cocci script: (and a little typing)
$ cat compare_ether_addr.cocci
@@
expression a,b;
@@
- !compare_ether_addr(a, b)
+ ether_addr_equal(a, b)
@@
expression a,b;
@@
- compare_ether_addr(a, b)
+ !ether_addr_equal(a, b)
@@
expression a,b;
@@
- !ether_addr_equal(a, b) == 0
+ ether_addr_equal(a, b)
@@
expression a,b;
@@
- !ether_addr_equal(a, b) != 0
+ !ether_addr_equal(a, b)
@@
expression a,b;
@@
- ether_addr_equal(a, b) == 0
+ !ether_addr_equal(a, b)
@@
expression a,b;
@@
- ether_addr_equal(a, b) != 0
+ ether_addr_equal(a, b)
@@
expression a,b;
@@
- !!ether_addr_equal(a, b)
+ ether_addr_equal(a, b)
Signed-off-by: Joe Perches <joe@perches.com>
---
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 4 ++--
drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c | 4 ++--
drivers/net/ethernet/tile/tilegx.c | 2 +-
drivers/net/usb/qmi_wwan.c | 2 +-
drivers/net/vxlan.c | 7 +++----
drivers/net/wireless/ath/carl9170/rx.c | 4 ++--
drivers/net/wireless/rt2x00/rt2x00dev.c | 4 ++--
drivers/net/wireless/rtlwifi/base.c | 2 +-
drivers/net/wireless/rtlwifi/ps.c | 2 +-
drivers/net/wireless/rtlwifi/rtl8188ee/trx.c | 9 +++++----
drivers/net/wireless/rtlwifi/rtl8723ae/trx.c | 20 ++++++++++----------
11 files changed, 30 insertions(+), 30 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 1f5166a..59a62bb 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -488,8 +488,8 @@ static bool ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector,
* source pruning.
*/
if ((skb->pkt_type & (PACKET_BROADCAST | PACKET_MULTICAST)) &&
- !(compare_ether_addr(adapter->netdev->dev_addr,
- eth_hdr(skb)->h_source))) {
+ ether_addr_equal(adapter->netdev->dev_addr,
+ eth_hdr(skb)->h_source)) {
dev_kfree_skb_irq(skb);
goto next_desc;
}
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c
index eb49cd6..f1261b1 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c
@@ -1639,14 +1639,14 @@ int qlcnic_sriov_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
if (!is_valid_ether_addr(mac) || vf >= num_vfs)
return -EINVAL;
- if (!compare_ether_addr(adapter->mac_addr, mac)) {
+ if (ether_addr_equal(adapter->mac_addr, mac)) {
netdev_err(netdev, "MAC address is already in use by the PF\n");
return -EINVAL;
}
for (i = 0; i < num_vfs; i++) {
vf_info = &sriov->vf_info[i];
- if (!compare_ether_addr(vf_info->vp->mac, mac)) {
+ if (ether_addr_equal(vf_info->vp->mac, mac)) {
netdev_err(netdev,
"MAC address is already in use by VF %d\n",
i);
diff --git a/drivers/net/ethernet/tile/tilegx.c b/drivers/net/ethernet/tile/tilegx.c
index 907b577..b05304e 100644
--- a/drivers/net/ethernet/tile/tilegx.c
+++ b/drivers/net/ethernet/tile/tilegx.c
@@ -544,7 +544,7 @@ static inline bool filter_packet(struct net_device *dev, void *buf)
/* Filter out packets that aren't for us. */
if (!(dev->flags & IFF_PROMISC) &&
!is_multicast_ether_addr(buf) &&
- compare_ether_addr(dev->dev_addr, buf) != 0)
+ !ether_addr_equal(dev->dev_addr, buf))
return true;
return false;
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index 606eba2..3a81315 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -323,7 +323,7 @@ next_desc:
/* Never use the same address on both ends of the link, even
* if the buggy firmware told us to.
*/
- if (!compare_ether_addr(dev->net->dev_addr, default_modem_addr))
+ if (ether_addr_equal(dev->net->dev_addr, default_modem_addr))
eth_hw_addr_random(dev->net);
/* make MAC addr easily distinguishable from an IP header */
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index c3dd6e4..92ae31d 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -371,7 +371,7 @@ static struct vxlan_fdb *__vxlan_find_mac(struct vxlan_dev *vxlan,
struct vxlan_fdb *f;
hlist_for_each_entry_rcu(f, head, hlist) {
- if (compare_ether_addr(mac, f->eth_addr) == 0)
+ if (ether_addr_equal(mac, f->eth_addr))
return f;
}
@@ -903,8 +903,7 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
skb->protocol = eth_type_trans(skb, vxlan->dev);
/* Ignore packet loops (and multicast echo) */
- if (compare_ether_addr(eth_hdr(skb)->h_source,
- vxlan->dev->dev_addr) == 0)
+ if (ether_addr_equal(eth_hdr(skb)->h_source, vxlan->dev->dev_addr))
goto drop;
if ((vxlan->flags & VXLAN_F_LEARN) &&
@@ -1054,7 +1053,7 @@ static bool route_shortcircuit(struct net_device *dev, struct sk_buff *skb)
if (n) {
bool diff;
- diff = compare_ether_addr(eth_hdr(skb)->h_dest, n->ha) != 0;
+ diff = !ether_addr_equal(eth_hdr(skb)->h_dest, n->ha);
if (diff) {
memcpy(eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest,
dev->addr_len);
diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c
index 4684dd9..e935f61 100644
--- a/drivers/net/wireless/ath/carl9170/rx.c
+++ b/drivers/net/wireless/ath/carl9170/rx.c
@@ -602,8 +602,8 @@ static void carl9170_ba_check(struct ar9170 *ar, void *data, unsigned int len)
if (bar->start_seq_num == entry_bar->start_seq_num &&
TID_CHECK(bar->control, entry_bar->control) &&
- compare_ether_addr(bar->ra, entry_bar->ta) == 0 &&
- compare_ether_addr(bar->ta, entry_bar->ra) == 0) {
+ ether_addr_equal(bar->ra, entry_bar->ta) &&
+ ether_addr_equal(bar->ta, entry_bar->ra)) {
struct ieee80211_tx_info *tx_info;
tx_info = IEEE80211_SKB_CB(entry_skb);
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index b16521e..712eea9 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -566,10 +566,10 @@ static void rt2x00lib_rxdone_check_ba(struct rt2x00_dev *rt2x00dev,
#undef TID_CHECK
- if (compare_ether_addr(ba->ra, entry->ta))
+ if (!ether_addr_equal(ba->ra, entry->ta))
continue;
- if (compare_ether_addr(ba->ta, entry->ra))
+ if (!ether_addr_equal(ba->ta, entry->ra))
continue;
/* Mark BAR since we received the according BA */
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c
index 7651f5a..8bb4a9a 100644
--- a/drivers/net/wireless/rtlwifi/base.c
+++ b/drivers/net/wireless/rtlwifi/base.c
@@ -1304,7 +1304,7 @@ void rtl_beacon_statistic(struct ieee80211_hw *hw, struct sk_buff *skb)
return;
/* and only beacons from the associated BSSID, please */
- if (compare_ether_addr(hdr->addr3, rtlpriv->mac80211.bssid))
+ if (!ether_addr_equal(hdr->addr3, rtlpriv->mac80211.bssid))
return;
rtlpriv->link_info.bcn_rx_inperiod++;
diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c
index 298b615..b593d24 100644
--- a/drivers/net/wireless/rtlwifi/ps.c
+++ b/drivers/net/wireless/rtlwifi/ps.c
@@ -923,7 +923,7 @@ void rtl_p2p_info(struct ieee80211_hw *hw, void *data, unsigned int len)
return;
/* and only beacons from the associated BSSID, please */
- if (compare_ether_addr(hdr->addr3, rtlpriv->mac80211.bssid))
+ if (!ether_addr_equal(hdr->addr3, rtlpriv->mac80211.bssid))
return;
/* check if this really is a beacon */
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c
index a8871d6..68685a8 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c
@@ -305,13 +305,14 @@ static void _rtl88ee_translate_rx_signal_stuff(struct ieee80211_hw *hw,
psaddr = ieee80211_get_SA(hdr);
memcpy(pstatus->psaddr, psaddr, ETH_ALEN);
- addr = (!compare_ether_addr(mac->bssid, (ufc & IEEE80211_FCTL_TODS) ?
- hdr->addr1 : (ufc & IEEE80211_FCTL_FROMDS) ?
- hdr->addr2 : hdr->addr3));
+ addr = ether_addr_equal(mac->bssid,
+ (ufc & IEEE80211_FCTL_TODS) ? hdr->addr1 :
+ (ufc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 :
+ hdr->addr3);
match_bssid = ((IEEE80211_FTYPE_CTL != type) && (!pstatus->hwerror) &&
(!pstatus->crc) && (!pstatus->icv)) && addr;
- addr = (!compare_ether_addr(praddr, rtlefuse->dev_addr));
+ addr = ether_addr_equal(praddr, rtlefuse->dev_addr);
packet_toself = match_bssid && addr;
if (ieee80211_is_beacon(fc))
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c
index c72758d..bcd82a1 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c
@@ -255,16 +255,16 @@ static void _rtl8723ae_translate_rx_signal_stuff(struct ieee80211_hw *hw,
type = WLAN_FC_GET_TYPE(fc);
praddr = hdr->addr1;
- packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) &&
- (!compare_ether_addr(mac->bssid,
- (le16_to_cpu(fc) & IEEE80211_FCTL_TODS) ?
- hdr->addr1 : (le16_to_cpu(fc) &
- IEEE80211_FCTL_FROMDS) ?
- hdr->addr2 : hdr->addr3)) && (!pstatus->hwerror) &&
- (!pstatus->crc) && (!pstatus->icv));
-
- packet_toself = packet_matchbssid &&
- (!compare_ether_addr(praddr, rtlefuse->dev_addr));
+ packet_matchbssid =
+ ((IEEE80211_FTYPE_CTL != type) &&
+ ether_addr_equal(mac->bssid,
+ (le16_to_cpu(fc) & IEEE80211_FCTL_TODS) ? hdr->addr1 :
+ (le16_to_cpu(fc) & IEEE80211_FCTL_FROMDS) ? hdr->addr2 :
+ hdr->addr3) &&
+ (!pstatus->hwerror) && (!pstatus->crc) && (!pstatus->icv));
+
+ packet_toself = (packet_matchbssid &&
+ ether_addr_equal(praddr, rtlefuse->dev_addr));
if (ieee80211_is_beacon(fc))
packet_beacon = true;
------------------------------------------------------------------------------
Learn the latest--Visual Studio 2012, SharePoint 2013, SQL 2012, more!
Discover the easy way to master current and previous Microsoft technologies
and advance your career. Get an incredible 1,500+ hours of step-by-step
tutorial videos with LearnDevNow. Subscribe today and save!
http://pubads.g.doubleclick.net/gampad/clk?id=58040911&iu=/4140/ostg.clktrk
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel® Ethernet, visit http://communities.intel.com/community/wired
^ permalink raw reply related
* Re: [PATCH] ipv6: ipv6_create_tempaddr cleanup
From: Hannes Frederic Sowa @ 2013-09-01 18:35 UTC (permalink / raw)
To: Petr Holasek; +Cc: David S. Miller, netdev, linux-kernel
In-Reply-To: <1377874958-2426-1-git-send-email-pholasek@redhat.com>
On Fri, Aug 30, 2013 at 05:02:38PM +0200, Petr Holasek wrote:
> This two-liner removes max_addresses variable which is now unecessary related
> to patch [ipv6: remove max_addresses check from ipv6_create_tempaddr].
>
> Signed-off-by: Petr Holasek <pholasek@redhat.com>
Uh, yes, I missed that. Thanks a lot!
Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
^ permalink raw reply
* [PATCH] USB2NET : SR9700 : One chip USB 1.1 USB2NET SR9700Device Driver Support
From: liujunliang_ljl @ 2013-09-01 11:38 UTC (permalink / raw)
To: davem
Cc: horms, joe, romieu, gregkh, netdev, linux-usb, linux-kernel,
sunhecheng, Liu Junliang
From: Liu Junliang <liujunliang_ljl@163.com>
Signed-off-by: Liu Junliang <liujunliang_ljl@163.com>
---
drivers/net/usb/Kconfig | 8 +
drivers/net/usb/Makefile | 1 +
drivers/net/usb/sr9700.c | 560 ++++++++++++++++++++++++++++++++++++++++++++++
drivers/net/usb/sr9700.h | 173 ++++++++++++++
4 files changed, 742 insertions(+)
create mode 100644 drivers/net/usb/sr9700.c
create mode 100644 drivers/net/usb/sr9700.h
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index 287cc62..a94b196 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -272,6 +272,14 @@ config USB_NET_DM9601
This option adds support for Davicom DM9601 based USB 1.1
10/100 Ethernet adapters.
+config USB_NET_SR9700
+ tristate "CoreChip-sz SR9700 based USB 1.1 10/100 ethernet devices"
+ depends on USB_USBNET
+ select CRC32
+ help
+ This option adds support for CoreChip-sz SR9700 based USB 1.1
+ 10/100 Ethernet adapters.
+
config USB_NET_SMSC75XX
tristate "SMSC LAN75XX based USB 2.0 gigabit ethernet devices"
depends on USB_USBNET
diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile
index 9ab5c9d..bba87a2 100644
--- a/drivers/net/usb/Makefile
+++ b/drivers/net/usb/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_USB_NET_AX88179_178A) += ax88179_178a.o
obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o
obj-$(CONFIG_USB_NET_CDC_EEM) += cdc_eem.o
obj-$(CONFIG_USB_NET_DM9601) += dm9601.o
+obj-$(CONFIG_USB_NET_SR9700) += sr9700.o
obj-$(CONFIG_USB_NET_SMSC75XX) += smsc75xx.o
obj-$(CONFIG_USB_NET_SMSC95XX) += smsc95xx.o
obj-$(CONFIG_USB_NET_GL620A) += gl620a.o
diff --git a/drivers/net/usb/sr9700.c b/drivers/net/usb/sr9700.c
new file mode 100644
index 0000000..7ec3e0e
--- /dev/null
+++ b/drivers/net/usb/sr9700.c
@@ -0,0 +1,560 @@
+/*
+ * CoreChip-sz SR9700 one chip USB 1.1 Ethernet Devices
+ *
+ * Author : Liu Junliang <liujunliang_ljl@163.com>
+ *
+ * Based on dm9601.c
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/stddef.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+#include <linux/crc32.h>
+#include <linux/usb/usbnet.h>
+
+#include "sr9700.h"
+
+static int sr_read(struct usbnet *dev, u8 reg, u16 length, void *data)
+{
+ int err;
+
+ err = usbnet_read_cmd(dev, SR_RD_REGS, SR_REQ_RD_REG, 0, reg, data,
+ length);
+ if ((err != length) && (err >= 0))
+ err = -EINVAL;
+ return err;
+}
+
+static int sr_write(struct usbnet *dev, u8 reg, u16 length, void *data)
+{
+ int err;
+
+ err = usbnet_write_cmd(dev, SR_WR_REGS, SR_REQ_WR_REG, 0, reg, data,
+ length);
+ if ((err >= 0) && (err < length))
+ err = -EINVAL;
+ return err;
+}
+
+static int sr_read_reg(struct usbnet *dev, u8 reg, u8 *value)
+{
+ return sr_read(dev, reg, 1, value);
+}
+
+static int sr_write_reg(struct usbnet *dev, u8 reg, u8 value)
+{
+ return usbnet_write_cmd(dev, SR_WR_REGS, SR_REQ_WR_REG,
+ value, reg, NULL, 0);
+}
+
+static void sr_write_async(struct usbnet *dev, u8 reg, u16 length, void *data)
+{
+ usbnet_write_cmd_async(dev, SR_WR_REGS, SR_REQ_WR_REG,
+ 0, reg, data, length);
+}
+
+static void sr_write_reg_async(struct usbnet *dev, u8 reg, u8 value)
+{
+ usbnet_write_cmd_async(dev, SR_WR_REGS, SR_REQ_WR_REG,
+ value, reg, NULL, 0);
+}
+
+static int wait_phy_eeprom_ready(struct usbnet *dev, int phy)
+{
+ int i;
+
+ for (i = 0; i < SR_SHARE_TIMEOUT; i++) {
+ u8 tmp = 0;
+ int ret;
+
+ udelay(1);
+ ret = sr_read_reg(dev, EPCR, &tmp);
+ if (ret < 0)
+ return ret;
+
+ /* ready */
+ if (!(tmp & EPCR_ERRE))
+ return 0;
+ }
+
+ netdev_err(dev->net, "%s write timed out!\n", phy ? "phy" : "eeprom");
+
+ return -EIO;
+}
+
+static int sr_share_read_word(struct usbnet *dev, int phy, u8 reg,
+ __le16 *value)
+{
+ int ret;
+
+ mutex_lock(&dev->phy_mutex);
+
+ sr_write_reg(dev, EPAR, phy ? (reg | EPAR_PHY_ADR) : reg);
+ sr_write_reg(dev, EPCR, phy ? (EPCR_EPOS | EPCR_ERPRR) : EPCR_ERPRR);
+
+ ret = wait_phy_eeprom_ready(dev, phy);
+ if (ret < 0)
+ goto out_unlock;
+
+ sr_write_reg(dev, EPCR, 0x0);
+ ret = sr_read(dev, EPDR, 2, value);
+
+ netdev_dbg(dev->net, "read shared %d 0x%02x returned 0x%04x, %d\n",
+ phy, reg, *value, ret);
+
+out_unlock:
+ mutex_unlock(&dev->phy_mutex);
+ return ret;
+}
+
+static int sr_share_write_word(struct usbnet *dev, int phy, u8 reg,
+ __le16 value)
+{
+ int ret;
+
+ mutex_lock(&dev->phy_mutex);
+
+ ret = sr_write(dev, EPDR, 2, &value);
+ if (ret < 0)
+ goto out_unlock;
+
+ sr_write_reg(dev, EPAR, phy ? (reg | EPAR_PHY_ADR) : reg);
+ sr_write_reg(dev, EPCR, phy ? (EPCR_WEP | EPCR_EPOS | EPCR_ERPRW) :
+ (EPCR_WEP | EPCR_ERPRW));
+
+ ret = wait_phy_eeprom_ready(dev, phy);
+ if (ret < 0)
+ goto out_unlock;
+
+ sr_write_reg(dev, EPCR, 0x0);
+
+out_unlock:
+ mutex_unlock(&dev->phy_mutex);
+ return ret;
+}
+
+static int sr_read_eeprom_word(struct usbnet *dev, u8 offset, void *value)
+{
+ return sr_share_read_word(dev, 0, offset, value);
+}
+
+static int sr9700_get_eeprom_len(struct net_device *netdev)
+{
+ return SR_EEPROM_LEN;
+}
+
+static int sr9700_get_eeprom(struct net_device *netdev,
+ struct ethtool_eeprom *eeprom, u8 *data)
+{
+ struct usbnet *dev = netdev_priv(netdev);
+ __le16 *buf = (__le16 *)data;
+ int ret = 0;
+ int i;
+
+ /* access is 16bit */
+ if ((eeprom->offset & 0x01) || (eeprom->len & 0x01))
+ return -EINVAL;
+
+ for (i = 0; i < eeprom->len / 2; i++) {
+ ret = sr_read_eeprom_word(dev, eeprom->offset / 2 + i, buf + i);
+ if (ret < 0)
+ break;
+ }
+
+ return ret;
+}
+
+static int sr_mdio_read(struct net_device *netdev, int phy_id, int loc)
+{
+ struct usbnet *dev = netdev_priv(netdev);
+ __le16 res;
+ int rc = 0;
+
+ if (phy_id) {
+ netdev_dbg(netdev, "Only internal phy supported\n");
+ return 0;
+ }
+
+ /* Access NSR_LINKST bit for link status instead of MII_BMSR */
+ if (loc == MII_BMSR) {
+ u8 value;
+
+ sr_read_reg(dev, NSR, &value);
+ if (value & NSR_LINKST)
+ rc = 1;
+ }
+ sr_share_read_word(dev, 1, loc, &res);
+ if (rc == 1)
+ res = le16_to_cpu(res) | BMSR_LSTATUS;
+ else
+ res = le16_to_cpu(res) & ~BMSR_LSTATUS;
+
+ netdev_dbg(netdev, "sr_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n",
+ phy_id, loc, res);
+
+ return res;
+}
+
+static void sr_mdio_write(struct net_device *netdev, int phy_id, int loc,
+ int val)
+{
+ struct usbnet *dev = netdev_priv(netdev);
+ __le16 res = cpu_to_le16(val);
+
+ if (phy_id) {
+ netdev_dbg(netdev, "Only internal phy supported\n");
+ return;
+ }
+
+ netdev_dbg(netdev, "sr_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n",
+ phy_id, loc, val);
+
+ sr_share_write_word(dev, 1, loc, res);
+}
+
+static u32 sr9700_get_link(struct net_device *netdev)
+{
+ struct usbnet *dev = netdev_priv(netdev);
+ u8 value = 0;
+ int rc = 0;
+
+ /* Get the Link Status directly */
+ sr_read_reg(dev, NSR, &value);
+ if (value & NSR_LINKST)
+ rc = 1;
+
+ return rc;
+}
+
+static int sr9700_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
+{
+ struct usbnet *dev = netdev_priv(netdev);
+
+ return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
+}
+
+static const struct ethtool_ops sr9700_ethtool_ops = {
+ .get_drvinfo = usbnet_get_drvinfo,
+ .get_link = sr9700_get_link,
+ .get_msglevel = usbnet_get_msglevel,
+ .set_msglevel = usbnet_set_msglevel,
+ .get_eeprom_len = sr9700_get_eeprom_len,
+ .get_eeprom = sr9700_get_eeprom,
+ .get_settings = usbnet_get_settings,
+ .set_settings = usbnet_set_settings,
+ .nway_reset = usbnet_nway_reset,
+};
+
+static void sr9700_set_multicast(struct net_device *netdev)
+{
+ struct usbnet *dev = netdev_priv(netdev);
+ /* We use the 20 byte dev->data for our 8 byte filter buffer
+ * to avoid allocating memory that is tricky to free later
+ */
+ u8 *hashes = (u8 *)&dev->data;
+ /* rx_ctl setting : enable, disable_long, disable_crc */
+ u8 rx_ctl = RCR_RXEN | RCR_DIS_CRC | RCR_DIS_LONG;
+
+ memset(hashes, 0x00, SR_MCAST_SIZE);
+ /* broadcast address */
+ hashes[SR_MCAST_SIZE - 1] |= SR_MCAST_ADDR_FLAG;
+ if (netdev->flags & IFF_PROMISC) {
+ rx_ctl |= RCR_PRMSC;
+ } else if (netdev->flags & IFF_ALLMULTI ||
+ netdev_mc_count(netdev) > SR_MCAST_MAX) {
+ rx_ctl |= RCR_RUNT;
+ } else if (!netdev_mc_empty(netdev)) {
+ struct netdev_hw_addr *ha;
+
+ netdev_for_each_mc_addr(ha, netdev) {
+ u32 crc = ether_crc(ETH_ALEN, ha->addr) >> 26;
+ hashes[crc >> 3] |= 1 << (crc & 0x7);
+ }
+ }
+
+ sr_write_async(dev, MAR, SR_MCAST_SIZE, hashes);
+ sr_write_reg_async(dev, RCR, rx_ctl);
+}
+
+static int sr9700_set_mac_address(struct net_device *netdev, void *p)
+{
+ struct usbnet *dev = netdev_priv(netdev);
+ struct sockaddr *addr = p;
+
+ if (!is_valid_ether_addr(addr->sa_data)) {
+ netdev_err(netdev, "not setting invalid mac address %pM\n",
+ addr->sa_data);
+ return -EINVAL;
+ }
+
+ memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
+ sr_write_async(dev, PAR, 6, netdev->dev_addr);
+
+ return 0;
+}
+
+static const struct net_device_ops sr9700_netdev_ops = {
+ .ndo_open = usbnet_open,
+ .ndo_stop = usbnet_stop,
+ .ndo_start_xmit = usbnet_start_xmit,
+ .ndo_tx_timeout = usbnet_tx_timeout,
+ .ndo_change_mtu = usbnet_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_do_ioctl = sr9700_ioctl,
+ .ndo_set_rx_mode = sr9700_set_multicast,
+ .ndo_set_mac_address = sr9700_set_mac_address,
+};
+
+static int sr9700_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+ struct net_device *netdev;
+ struct mii_if_info *mii;
+ int ret;
+
+ ret = usbnet_get_endpoints(dev, intf);
+ if (ret)
+ goto out;
+
+ netdev = dev->net;
+
+ netdev->netdev_ops = &sr9700_netdev_ops;
+ netdev->ethtool_ops = &sr9700_ethtool_ops;
+ netdev->hard_header_len += SR_TX_OVERHEAD;
+ dev->hard_mtu = netdev->mtu + netdev->hard_header_len;
+ /* bulkin buffer is preferably not less than 3K */
+ dev->rx_urb_size = 3072;
+
+ mii = &dev->mii;
+ mii->dev = netdev;
+ mii->mdio_read = sr_mdio_read;
+ mii->mdio_write = sr_mdio_write;
+ mii->phy_id_mask = 0x1f;
+ mii->reg_num_mask = 0x1f;
+
+ sr_write_reg(dev, NCR, NCR_RST);
+ udelay(20);
+
+ /* read MAC
+ * After Chip Power on, the Chip will reload the MAC from
+ * EEPROM automatically to PAR. In case there is no EEPROM externally,
+ * a default MAC address is stored in PAR for making chip work properly.
+ */
+ if (sr_read(dev, PAR, ETH_ALEN, netdev->dev_addr) < 0) {
+ netdev_err(netdev, "Error reading MAC address\n");
+ ret = -ENODEV;
+ goto out;
+ }
+
+ /* power up and reset phy */
+ sr_write_reg(dev, PRR, PRR_PHY_RST);
+ /* at least 10ms, here 20ms for safe */
+ mdelay(20);
+ sr_write_reg(dev, PRR, 0);
+ /* at least 1ms, here 2ms for reading right register */
+ udelay(2 * 1000);
+
+ /* receive broadcast packets */
+ sr9700_set_multicast(netdev);
+
+ sr_mdio_write(netdev, mii->phy_id, MII_BMCR, BMCR_RESET);
+ sr_mdio_write(netdev, mii->phy_id, MII_ADVERTISE, ADVERTISE_ALL |
+ ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
+ mii_nway_restart(mii);
+
+out:
+ return ret;
+}
+
+static int sr9700_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+ struct sk_buff *sr_skb;
+ int len;
+
+ /* skb content (packets) format :
+ * p0 p1 p2 ...... pm
+ * / \
+ * / \
+ * / \
+ * / \
+ * p0b0 p0b1 p0b2 p0b3 ...... p0b(n-4) p0b(n-3)...p0bn
+ *
+ * p0 : packet 0
+ * p0b0 : packet 0 byte 0
+ *
+ * b0: rx status
+ * b1: packet length (incl crc) low
+ * b2: packet length (incl crc) high
+ * b3..n-4: packet data
+ * bn-3..bn: ethernet packet crc
+ */
+ if (unlikely(skb->len < SR_RX_OVERHEAD)) {
+ netdev_err(dev->net, "unexpected tiny rx frame\n");
+ return 0;
+ }
+
+ /* one skb may contains multiple packets */
+ while (skb->len > SR_RX_OVERHEAD) {
+ if (skb->data[0] != 0x40)
+ return 0;
+
+ /* ignore the CRC length */
+ len = (skb->data[1] | (skb->data[2] << 8)) - 4;
+
+ if (len > ETH_FRAME_LEN)
+ return 0;
+
+ /* the last packet of current skb */
+ if (skb->len == (len + SR_RX_OVERHEAD)) {
+ skb_pull(skb, 3);
+ skb->len = len;
+ skb_set_tail_pointer(skb, len);
+ skb->truesize = len + sizeof(struct sk_buff);
+ return 2;
+ }
+
+ /* skb_clone is used for address align */
+ sr_skb = skb_clone(skb, GFP_ATOMIC);
+ if (!sr_skb)
+ return 0;
+
+ sr_skb->len = len;
+ sr_skb->data = skb->data + 3;
+ skb_set_tail_pointer(sr_skb, len);
+ sr_skb->truesize = len + sizeof(struct sk_buff);
+ usbnet_skb_return(dev, sr_skb);
+
+ skb_pull(skb, len + SR_RX_OVERHEAD);
+ };
+
+ return 0;
+}
+
+static struct sk_buff *sr9700_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
+ gfp_t flags)
+{
+ int len;
+
+ /* SR9700 can only send out one ethernet packet at once.
+ *
+ * b0 b1 b2 b3 ...... b(n-4) b(n-3)...bn
+ *
+ * b0: rx status
+ * b1: packet length (incl crc) low
+ * b2: packet length (incl crc) high
+ * b3..n-4: packet data
+ * bn-3..bn: ethernet packet crc
+ */
+
+ len = skb->len;
+
+ if (skb_headroom(skb) < SR_TX_OVERHEAD) {
+ struct sk_buff *skb2;
+
+ skb2 = skb_copy_expand(skb, SR_TX_OVERHEAD, 0, flags);
+ dev_kfree_skb_any(skb);
+ skb = skb2;
+ if (!skb)
+ return NULL;
+ }
+
+ __skb_push(skb, SR_TX_OVERHEAD);
+
+ /* usbnet adds padding if length is a multiple of packet size
+ * if so, adjust length value in header
+ */
+ if ((skb->len % dev->maxpacket) == 0)
+ len++;
+
+ skb->data[0] = len;
+ skb->data[1] = len >> 8;
+
+ return skb;
+}
+
+static void sr9700_status(struct usbnet *dev, struct urb *urb)
+{
+ int link;
+ u8 *buf;
+
+ /* format:
+ b0: net status
+ b1: tx status 1
+ b2: tx status 2
+ b3: rx status
+ b4: rx overflow
+ b5: rx count
+ b6: tx count
+ b7: gpr
+ */
+
+ if (urb->actual_length < 8)
+ return;
+
+ buf = urb->transfer_buffer;
+
+ link = !!(buf[0] & 0x40);
+ if (netif_carrier_ok(dev->net) != link) {
+ usbnet_link_change(dev, link, 1);
+ netdev_dbg(dev->net, "Link Status is: %d\n", link);
+ }
+}
+
+static int sr9700_link_reset(struct usbnet *dev)
+{
+ struct ethtool_cmd ecmd;
+
+ mii_check_media(&dev->mii, 1, 1);
+ mii_ethtool_gset(&dev->mii, &ecmd);
+
+ netdev_dbg(dev->net, "link_reset() speed: %d duplex: %d\n",
+ ecmd.speed, ecmd.duplex);
+
+ return 0;
+}
+
+static const struct driver_info sr9700_driver_info = {
+ .description = "CoreChip SR9700 USB Ethernet",
+ .flags = FLAG_ETHER,
+ .bind = sr9700_bind,
+ .rx_fixup = sr9700_rx_fixup,
+ .tx_fixup = sr9700_tx_fixup,
+ .status = sr9700_status,
+ .link_reset = sr9700_link_reset,
+ .reset = sr9700_link_reset,
+};
+
+static const struct usb_device_id products[] = {
+ {
+ USB_DEVICE(0x0fe6, 0x9700), /* SR9700 device */
+ .driver_info = (unsigned long)&sr9700_driver_info,
+ },
+ {}, /* END */
+};
+
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver sr9700_usb_driver = {
+ .name = "sr9700",
+ .id_table = products,
+ .probe = usbnet_probe,
+ .disconnect = usbnet_disconnect,
+ .suspend = usbnet_suspend,
+ .resume = usbnet_resume,
+ .disable_hub_initiated_lpm = 1,
+};
+
+module_usb_driver(sr9700_usb_driver);
+
+MODULE_AUTHOR("liujl <liujunliang_ljl@163.com>");
+MODULE_DESCRIPTION("SR9700 one chip USB 1.1 USB to Ethernet device from http://www.corechip-sz.com/");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/usb/sr9700.h b/drivers/net/usb/sr9700.h
new file mode 100644
index 0000000..fd687c5
--- /dev/null
+++ b/drivers/net/usb/sr9700.h
@@ -0,0 +1,173 @@
+/*
+ * CoreChip-sz SR9700 one chip USB 1.1 Ethernet Devices
+ *
+ * Author : Liu Junliang <liujunliang_ljl@163.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ */
+
+#ifndef _SR9700_H
+#define _SR9700_H
+
+/* sr9700 spec. register table on Linux platform */
+
+/* Network Control Reg */
+#define NCR 0x00
+#define NCR_RST (1 << 0)
+#define NCR_LBK (3 << 1)
+#define NCR_FDX (1 << 3)
+#define NCR_WAKEEN (1 << 6)
+/* Network Status Reg */
+#define NSR 0x01
+#define NSR_RXRDY (1 << 0)
+#define NSR_RXOV (1 << 1)
+#define NSR_TX1END (1 << 2)
+#define NSR_TX2END (1 << 3)
+#define NSR_TXFULL (1 << 4)
+#define NSR_WAKEST (1 << 5)
+#define NSR_LINKST (1 << 6)
+#define NSR_SPEED (1 << 7)
+/* Tx Control Reg */
+#define TCR 0x02
+#define TCR_CRC_DIS (1 << 1)
+#define TCR_PAD_DIS (1 << 2)
+#define TCR_LC_CARE (1 << 3)
+#define TCR_CRS_CARE (1 << 4)
+#define TCR_EXCECM (1 << 5)
+#define TCR_LF_EN (1 << 6)
+/* Tx Status Reg for Packet Index 1 */
+#define TSR1 0x03
+#define TSR1_EC (1 << 2)
+#define TSR1_COL (1 << 3)
+#define TSR1_LC (1 << 4)
+#define TSR1_NC (1 << 5)
+#define TSR1_LOC (1 << 6)
+#define TSR1_TLF (1 << 7)
+/* Tx Status Reg for Packet Index 2 */
+#define TSR2 0x04
+#define TSR2_EC (1 << 2)
+#define TSR2_COL (1 << 3)
+#define TSR2_LC (1 << 4)
+#define TSR2_NC (1 << 5)
+#define TSR2_LOC (1 << 6)
+#define TSR2_TLF (1 << 7)
+/* Rx Control Reg*/
+#define RCR 0x05
+#define RCR_RXEN (1 << 0)
+#define RCR_PRMSC (1 << 1)
+#define RCR_RUNT (1 << 2)
+#define RCR_ALL (1 << 3)
+#define RCR_DIS_CRC (1 << 4)
+#define RCR_DIS_LONG (1 << 5)
+/* Rx Status Reg */
+#define RSR 0x06
+#define RSR_AE (1 << 2)
+#define RSR_MF (1 << 6)
+#define RSR_RF (1 << 7)
+/* Rx Overflow Counter Reg */
+#define ROCR 0x07
+#define ROCR_ROC (0x7F << 0)
+#define ROCR_RXFU (1 << 7)
+/* Back Pressure Threshold Reg */
+#define BPTR 0x08
+#define BPTR_JPT (0x0F << 0)
+#define BPTR_BPHW (0x0F << 4)
+/* Flow Control Threshold Reg */
+#define FCTR 0x09
+#define FCTR_LWOT (0x0F << 0)
+#define FCTR_HWOT (0x0F << 4)
+/* rx/tx Flow Control Reg */
+#define FCR 0x0A
+#define FCR_FLCE (1 << 0)
+#define FCR_BKPA (1 << 4)
+#define FCR_TXPEN (1 << 5)
+#define FCR_TXPF (1 << 6)
+#define FCR_TXP0 (1 << 7)
+/* Eeprom & Phy Control Reg */
+#define EPCR 0x0B
+#define EPCR_ERRE (1 << 0)
+#define EPCR_ERPRW (1 << 1)
+#define EPCR_ERPRR (1 << 2)
+#define EPCR_EPOS (1 << 3)
+#define EPCR_WEP (1 << 4)
+/* Eeprom & Phy Address Reg */
+#define EPAR 0x0C
+#define EPAR_EROA (0x3F << 0)
+#define EPAR_PHY_ADR_MASK (0x03 << 6)
+#define EPAR_PHY_ADR (0x01 << 6)
+/* Eeprom & Phy Data Reg */
+#define EPDR 0x0D /* 0x0D ~ 0x0E for Data Reg Low & High */
+/* Wakeup Control Reg */
+#define WCR 0x0F
+#define WCR_MAGICST (1 << 0)
+#define WCR_LINKST (1 << 2)
+#define WCR_MAGICEN (1 << 3)
+#define WCR_LINKEN (1 << 5)
+/* Physical Address Reg */
+#define PAR 0x10 /* 0x10 ~ 0x15 6 bytes for PAR */
+/* Multicast Address Reg */
+#define MAR 0x16 /* 0x16 ~ 0x1D 8 bytes for MAR */
+/* 0x1e unused */
+/* Phy Reset Reg */
+#define PRR 0x1F
+#define PRR_PHY_RST (1 << 0)
+/* Tx sdram Write Pointer Address Low */
+#define TWPAL 0x20
+/* Tx sdram Write Pointer Address High */
+#define TWPAH 0x21
+/* Tx sdram Read Pointer Address Low */
+#define TRPAL 0x22
+/* Tx sdram Read Pointer Address High */
+#define TRPAH 0x23
+/* Rx sdram Write Pointer Address Low */
+#define RWPAL 0x24
+/* Rx sdram Write Pointer Address High */
+#define RWPAH 0x25
+/* Rx sdram Read Pointer Address Low */
+#define RRPAL 0x26
+/* Rx sdram Read Pointer Address High */
+#define RRPAH 0x27
+/* Vendor ID register */
+#define VID 0x28 /* 0x28 ~ 0x29 2 bytes for VID */
+/* Product ID register */
+#define PID 0x2A /* 0x2A ~ 0x2B 2 bytes for PID */
+/* CHIP Revision register */
+#define CHIPR 0x2C
+/* 0x2D --> 0xEF unused */
+/* USB Device Address */
+#define USBDA 0xF0
+#define USBDA_USBFA (0x7F << 0)
+/* RX packet Counter Reg */
+#define RXC 0xF1
+/* Tx packet Counter & USB Status Reg */
+#define TXC_USBS 0xF2
+#define TXC_USBS_TXC0 (1 << 0)
+#define TXC_USBS_TXC1 (1 << 1)
+#define TXC_USBS_TXC2 (1 << 2)
+#define TXC_USBS_EP1RDY (1 << 5)
+#define TXC_USBS_SUSFLAG (1 << 6)
+#define TXC_USBS_RXFAULT (1 << 7)
+/* USB Control register */
+#define USBC 0xF4
+#define USBC_EP3NAK (1 << 4)
+#define USBC_EP3ACK (1 << 5)
+
+/* Register access commands and flags */
+#define SR_RD_REGS 0x00
+#define SR_WR_REGS 0x01
+#define SR_WR_REG 0x03
+#define SR_REQ_RD_REG (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE)
+#define SR_REQ_WR_REG (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE)
+
+/* parameters */
+#define SR_SHARE_TIMEOUT 1000
+#define SR_EEPROM_LEN 256
+#define SR_MCAST_SIZE 8
+#define SR_MCAST_ADDR_FLAG 0x80
+#define SR_MCAST_MAX 64
+#define SR_TX_OVERHEAD 2 /* 2bytes header */
+#define SR_RX_OVERHEAD 7 /* 3bytes header + 4crc tail */
+
+#endif /* _SR9700_H */
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH] rtl8187: fix use after free on failure path in rtl8187_init_urbs()
From: Hin-Tak Leung @ 2013-09-01 7:51 UTC (permalink / raw)
To: khoroshilov, herton, larry.finger
Cc: linville, linux-wireless, netdev, linux-kernel, ldv-project
------------------------------
On Sat, Aug 31, 2013 22:18 BST Alexey Khoroshilov wrote:
>In case of __dev_alloc_skb() failure rtl8187_init_urbs()
>calls usb_free_urb(entry) where 'entry' can points to urb
>allocated at the previous iteration. That means refcnt will be
>decremented incorrectly and the urb can be used after memory
>deallocation.
>
>The patch fixes the issue and implements error handling of init_urbs
>in rtl8187_start().
>
>Found by Linux Driver Verification project (linuxtesting.org).
>
>Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
>---
> drivers/net/wireless/rtl818x/rtl8187/dev.c | 15 ++++++++++-----
> 1 file changed, 10 insertions(+), 5 deletions(-)
>
>diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c
>index f49220e..e83d53c 100644
>--- a/drivers/net/wireless/rtl818x/rtl8187/dev.c
>+++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c
>@@ -438,17 +438,16 @@ static int rtl8187_init_urbs(struct ieee80211_hw *dev)
> skb_queue_tail(&priv->rx_queue, skb);
> usb_anchor_urb(entry, &priv->anchored);
> ret = usb_submit_urb(entry, GFP_KERNEL);
>+ usb_free_urb(entry);
> if (ret) {
> skb_unlink(skb, &priv->rx_queue);
> usb_unanchor_urb(entry);
> goto err;
> }
>- usb_free_urb(entry);
> }
> return ret;
>
> err:
>- usb_free_urb(entry);
> kfree_skb(skb);
> usb_kill_anchored_urbs(&priv->anchored);
> return ret;
This part looks wrong - you free_urb(entry) then unanchor_urb(entry).
>@@ -956,8 +955,12 @@ static int rtl8187_start(struct ieee80211_hw *dev)
> (RETRY_COUNT < 8 /* short retry limit */) |
> (RETRY_COUNT < 0 /* long retry limit */) |
> (7 < 21 /* MAX TX DMA */));
>- rtl8187_init_urbs(dev);
>- rtl8187b_init_status_urb(dev);
>+ ret = rtl8187_init_urbs(dev);
>+ if (ret)
>+ goto rtl8187_start_exit;
>+ ret = rtl8187b_init_status_urb(dev);
>+ if (ret)
>+ usb_kill_anchored_urbs(&priv->anchored);
> goto rtl8187_start_exit;
> }
>
>@@ -966,7 +969,9 @@ static int rtl8187_start(struct ieee80211_hw *dev)
> rtl818x_iowrite32(priv, &priv->map->MAR[0], ~0);
> rtl818x_iowrite32(priv, &priv->map->MAR[1], ~0);
>
>- rtl8187_init_urbs(dev);
>+ ret = rtl8187_init_urbs(dev);
>+ if (ret)
>+ goto rtl8187_start_exit;
>
> reg = RTL818X_RX_CONF_ONLYERLPKT |
> RTL818X_RX_CONF_RX_AUTORESETPHY |
>--
>1.8.1.2
>
^ permalink raw reply
* Re: [PATCH v2 net-next 0/9] set addr_assign_type when inheriting a dev_addr
From: David Miller @ 2013-09-01 2:50 UTC (permalink / raw)
To: bjorn
Cc: netdev, kaber, jiri, linville, linux-wireless, j, libertas-dev,
gregkh, devel, forest, stephen, dan.carpenter
In-Reply-To: <1377878932-26881-1-git-send-email-bjorn@mork.no>
From: Bjørn Mork <bjorn@mork.no>
Date: Fri, 30 Aug 2013 18:08:43 +0200
> Copying the dev_addr from a parent device is an operation
> common to a number of drivers. The addr_assign_type should
> be updated accordingly, either by reusing the value from
> the source device or explicitly indicating that the address
> is stolen by setting addr_assign_type to NET_ADDR_STOLEN.
>
> This patch set adds a helper copying both the dev_addr and
> the addr_assign_type, and use this helper in drivers which
> don't currently set the addr_assign_type. Using NET_ADDR_STOLEN
> might be more appropriate in some of these cases. Please
> let me know, and I'll update the patch accordingly.
>
> Changes in v2:
> - assuming addr_len == ETH_ALEN to allow optimized memcpy
> - dropped the vt6656 patch due to addr_len being unset in that driver
Looks good, series applied, thanks.
^ permalink raw reply
* Re: [PATCH net-next 0/9] qlcnic: Enhancements and cleanup
From: David Miller @ 2013-09-01 2:35 UTC (permalink / raw)
To: shahed.shaikh; +Cc: netdev, Dept-HSGLinuxNICDev
In-Reply-To: <1377885084-6441-1-git-send-email-shahed.shaikh@qlogic.com>
From: Shahed Shaikh <shahed.shaikh@qlogic.com>
Date: Fri, 30 Aug 2013 13:51:15 -0400
> From: Shahed Shaikh <shahed.shaikh@qlogic.com>
>
> This patch series contains -
> * Enhanced PVID handling for 84xx adapters by
> not indicating PVID configuration to VF driver and
> keeping VF driver in no VLAN configuration mode becasue
> adapter supports VLAN stripping.
> * Removed inappropriate usage of inline keyword.
> * Enhanced minidump feature by using firmware recommended
> dump capture mask and using CAMRAM register to store
> firmware dump state.
> * AER handling support for 83xx adapter.
> * Added support for per port eswitch configuration.
>
> Please apply to net-next.
Series applied, thank you.
^ permalink raw reply
* Re: [PATCH net-next v12 00/11] vxlan: add ipv6 support
From: David Miller @ 2013-09-01 2:30 UTC (permalink / raw)
To: amwang; +Cc: netdev
In-Reply-To: <1377927878-23975-1-git-send-email-amwang@redhat.com>
Ok, this has gone through enough revisions I think :-)
All applied, and please try to address any problems people run into
from here on out.
Thank you.
^ permalink raw reply
* Re: Pull request: sfc-next 2013-08-30
From: David Miller @ 2013-09-01 2:28 UTC (permalink / raw)
To: bhutchings; +Cc: netdev, linux-net-drivers
In-Reply-To: <1377833794.2552.26.camel@deadeye.wl.decadent.org.uk>
From: Ben Hutchings <bhutchings@solarflare.com>
Date: Fri, 30 Aug 2013 04:36:34 +0100
> 1. A little more refactoring.
> 2. Remove the unnecessary use of atomic_t that you pointed out.
> 3. Add support for starting or queueing firmware requests from atomic
> context.
> 4. Add hwmon support for additional sensors found on some new boards.
> 5. Add support for the EF10 controller architecture, the SFC9100 family
> and specifically the SFC9120 controller.
Pulled, thanks Ben.
Maybe you can get away with just doing "atomic_inc_return()" for the
MCDI sequence number bump and avoid the iface lock in those paths?
Just an idea.
^ permalink raw reply
* Good day
From: Cham Tao Soon @ 2013-08-31 15:15 UTC (permalink / raw)
To: netdev
Good day,
This is a personal email directed to you for your consideration alone, I request that it remain and be treated as such only. I am Mr. Cham Tao Soon, Chairman Audit Committee of UOB Bank, Singapore. I have an interesting business proposal for you that will be of immense benefit to both of us. Although this may be hard for you to believe, we stand to gain €105,000,000.00 EUR between us in a matter of days. Please grant me the benefit of doubt and hear me out. I need you to signify your interest by replying to this email.
Most importantly, I will need you to promise to keep whatever you learn from me between us even if you decide not to go along with me. I will make more details available to you on receipt of a positive response from you.
Greetings
Mr. Cham Tao Soon.
^ permalink raw reply
* Re: [PATCH net-next] etherdevice: Optimize compare_ether_addr/ether_addr_equal
From: David Miller @ 2013-08-31 22:27 UTC (permalink / raw)
To: joe; +Cc: eric.dumazet, netdev
In-Reply-To: <1377939256.2054.11.camel@joe-AO722>
From: Joe Perches <joe@perches.com>
Date: Sat, 31 Aug 2013 01:54:16 -0700
> When CONFIG_HAS_EFFICIENT_UNALIGNED_ACCESS is set,
> optimize compare_ether_addr a little by removing an
> xor and or by using a u32 and u16 comparison
> instead of 3 separate u16 comparisons.
>
> Make the ether_addr_equal_64bits code a bit simpler
> by adding a test for CONFIG_64BIT and calling
> ether_addr_equal otherwise.
>
> This also slightly improves ether_addr_equal_64bits
> by removing the zap_last_2bytes shifts in the !64bit
> case.
>
> Signed-off-by: Joe Perches <joe@perches.com>
You'll need to update Documantion/unaligned-memory-access.txt as well
because it uses this funcation as a "real life" example.
^ 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