* Re: [PATCH net-next 0/2] Address reference counting issues with sock_queue_err_skb
From: David Miller @ 2014-09-12 21:51 UTC (permalink / raw)
To: alexander.h.duyck
Cc: netdev, linux-wireless, johannes, eric.dumazet, linville
In-Reply-To: <20140910215837.23225.39149.stgit@ahduyck-bv4.jf.intel.com>
From: Alexander Duyck <alexander.h.duyck@intel.com>
Date: Wed, 10 Sep 2014 18:04:42 -0400
> After looking over the code for skb_clone_sk after some comments made by
> Eric Dumazet I have come to the conclusion that skb_clone_sk is taking the
> correct approach in how to handle the sk_refcnt when creating a buffer that
> is eventually meant to be returned to the socket via the sock_queue_err_skb
> function.
>
> However upon review of other callers I found what I believe to be a
> possible reference count issue in the path for handling "wifi ack" packets.
> To address this I have applied the same logic that is currently in place so
> that the sk_refcnt will be forced to stay at least 1, or we will not
> provide an skb to return in the sk_error_queue.
Series applied, thanks Alex.
^ permalink raw reply
* Re: RFC: DSA device/driver model revamp
From: David Miller @ 2014-09-12 21:50 UTC (permalink / raw)
To: f.fainelli; +Cc: netdev, jogo, nbd, alexander.duyck, jhs, kernel
In-Reply-To: <5410CCA6.8080506@gmail.com>
From: Florian Fainelli <f.fainelli@gmail.com>
Date: Wed, 10 Sep 2014 15:11:50 -0700
> Proposed solution:
No objections from me.
> Open questions:
>
> There is some legacy code that will instantiate the special "dsa"
> platform device in arch/arm/mach-orion5x/*, this code needs to be
> transitioned one way or the other.
>
> The switches used by these Orion5x platforms are MDIO-connected
> switches, with the proposal above, these switch drivers will become PHY
> drivers matching a particular PHY ID on the MDIO bus.
>
> We currently do not have a way to attach platform specific data that is
> not coming from Device Tree to these PHY devices, something potentially
> not too intrusive could be to extend phy_register_fixup() with a void *
> argument to pass specific platform data, or create
> phy_register_fixup_with_data().
I'd rather you create a new interface which is strongly typed than
anything using void pointers.
^ permalink raw reply
* Re: [net-next v5 1/3] udp-tunnel: Expand UDP tunnel APIs
From: Tom Herbert @ 2014-09-12 21:35 UTC (permalink / raw)
To: Andy Zhou; +Cc: David Miller, Linux Netdev List
In-Reply-To: <1410406193-6185-2-git-send-email-azhou@nicira.com>
On Wed, Sep 10, 2014 at 8:29 PM, Andy Zhou <azhou@nicira.com> wrote:
> Added common udp tunnel socket creation, and packet transmission APIs
> API that can be used by other UDP based tunneling protocol
> implementation.
>
> Signed-off-by: Andy Zhou <azhou@nicira.com>
> ---
> include/net/udp_tunnel.h | 73 +++++++++++++++++++++++++++
> net/ipv4/Kconfig | 1 +
> net/ipv4/udp_tunnel.c | 108 ++++++++++++++++++++++++++--------------
> net/ipv6/Makefile | 1 +
> net/ipv6/ip6_udp_tunnel.c | 121 +++++++++++++++++++++++++++++++++++++++++++++
> 5 files changed, 268 insertions(+), 36 deletions(-)
> create mode 100644 net/ipv6/ip6_udp_tunnel.c
>
> diff --git a/include/net/udp_tunnel.h b/include/net/udp_tunnel.h
> index ffd69cb..e9dcf83 100644
> --- a/include/net/udp_tunnel.h
> +++ b/include/net/udp_tunnel.h
> @@ -1,6 +1,14 @@
> #ifndef __NET_UDP_TUNNEL_H
> #define __NET_UDP_TUNNEL_H
>
> +#include <net/ip_tunnels.h>
> +#include <net/udp.h>
> +
> +#if IS_ENABLED(CONFIG_IPV6)
> +#include <net/ipv6.h>
> +#include <net/addrconf.h>
> +#endif
> +
> struct udp_port_cfg {
> u8 family;
>
> @@ -29,4 +37,69 @@ struct udp_port_cfg {
> int udp_sock_create(struct net *net, struct udp_port_cfg *cfg,
> struct socket **sockp);
>
> +#if IS_ENABLED(CONFIG_IPV6)
> +int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg,
> + struct socket **sockp);
> +#else
> +static inline int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg,
> + struct socket **sockp)
> +{
> + return 0;
> +}
> +#endif
> +
> +struct udp_tunnel_sock;
> +
> +typedef int (*udp_tunnel_encap_rcv_t)(struct sock *sk, struct sk_buff *skb);
> +typedef void (*udp_tunnel_encap_destroy_t)(struct sock *sk);
> +
> +struct udp_tunnel_sock_cfg {
> + struct socket *sock; /* The socket UDP tunnel will attach to */
> + /* Used for setting up udp_sock fields, see udp.h for details */
> + __u8 encap_type;
> + udp_tunnel_encap_rcv_t encap_rcv;
> + udp_tunnel_encap_destroy_t encap_destroy;
> +};
> +
> +struct udp_tunnel_sock {
> + struct socket *sock;
> +};
> +
> +struct udp_tunnel_sock *create_udp_tunnel_sock(struct net *net, size_t size,
> + struct udp_tunnel_sock_cfg
> + *sock_cfg);
> +
> +int udp_tunnel_xmit_skb(struct udp_tunnel_sock *uts, struct rtable *rt,
> + struct sk_buff *skb, __be32 src, __be32 dst,
> + __u8 tos, __u8 ttl, __be16 df, __be16 src_port,
> + __be16 dst_port, bool xnet);
> +
> +#if IS_ENABLED(CONFIG_IPV6)
> +int udp_tunnel6_xmit_skb(struct udp_tunnel_sock *uts, struct dst_entry *dst,
> + struct sk_buff *skb, struct net_device *dev,
> + struct in6_addr *saddr, struct in6_addr *daddr,
> + __u8 prio, __u8 ttl, __be16 src_port,
> + __be16 dst_port);
> +#endif
> +
> +void udp_tunnel_sock_release(struct udp_tunnel_sock *uts);
> +void udp_tunnel_sock_free(struct udp_tunnel_sock *uts);
> +
> +static inline struct sk_buff *udp_tunnel_handle_offloads(struct sk_buff *skb,
> + bool udp_csum)
> +{
> + int type = udp_csum ? SKB_GSO_UDP_TUNNEL_CSUM : SKB_GSO_UDP_TUNNEL;
> +
> + return iptunnel_handle_offloads(skb, udp_csum, type);
> +}
> +
> +static inline void udp_tunnel_encap_enable(struct socket *sock)
> +{
> +#if IS_ENABLED(CONFIG_IPV6)
> + if (sock->sk->sk_family == PF_INET6)
> + ipv6_stub->udpv6_encap_enable();
> + else
> +#endif
> + udp_encap_enable();
> +}
> #endif
> diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
> index dbc10d8..cccb95f 100644
> --- a/net/ipv4/Kconfig
> +++ b/net/ipv4/Kconfig
> @@ -308,6 +308,7 @@ config NET_IPVTI
> on top.
>
> config NET_UDP_TUNNEL
> + depends on (IPV6 || IPV6=n)
> tristate
> default n
>
> diff --git a/net/ipv4/udp_tunnel.c b/net/ipv4/udp_tunnel.c
> index 61ec1a6..d60c1a0 100644
> --- a/net/ipv4/udp_tunnel.c
> +++ b/net/ipv4/udp_tunnel.c
> @@ -14,42 +14,9 @@ int udp_sock_create(struct net *net, struct udp_port_cfg *cfg,
> int err = -EINVAL;
> struct socket *sock = NULL;
>
> -#if IS_ENABLED(CONFIG_IPV6)
> if (cfg->family == AF_INET6) {
> - struct sockaddr_in6 udp6_addr;
> -
> - err = sock_create_kern(AF_INET6, SOCK_DGRAM, 0, &sock);
> - if (err < 0)
> - goto error;
> -
> - sk_change_net(sock->sk, net);
> -
> - udp6_addr.sin6_family = AF_INET6;
> - memcpy(&udp6_addr.sin6_addr, &cfg->local_ip6,
> - sizeof(udp6_addr.sin6_addr));
> - udp6_addr.sin6_port = cfg->local_udp_port;
> - err = kernel_bind(sock, (struct sockaddr *)&udp6_addr,
> - sizeof(udp6_addr));
> - if (err < 0)
> - goto error;
> -
> - if (cfg->peer_udp_port) {
> - udp6_addr.sin6_family = AF_INET6;
> - memcpy(&udp6_addr.sin6_addr, &cfg->peer_ip6,
> - sizeof(udp6_addr.sin6_addr));
> - udp6_addr.sin6_port = cfg->peer_udp_port;
> - err = kernel_connect(sock,
> - (struct sockaddr *)&udp6_addr,
> - sizeof(udp6_addr), 0);
> - }
> - if (err < 0)
> - goto error;
> -
> - udp_set_no_check6_tx(sock->sk, !cfg->use_udp6_tx_checksums);
> - udp_set_no_check6_rx(sock->sk, !cfg->use_udp6_rx_checksums);
> - } else
> -#endif
> - if (cfg->family == AF_INET) {
> + return udp_sock_create6(net, cfg, sockp);
> + } else if (cfg->family == AF_INET) {
> struct sockaddr_in udp_addr;
>
> err = sock_create_kern(AF_INET, SOCK_DGRAM, 0, &sock);
> @@ -82,7 +49,6 @@ int udp_sock_create(struct net *net, struct udp_port_cfg *cfg,
> return -EPFNOSUPPORT;
> }
>
> -
> *sockp = sock;
>
> return 0;
> @@ -97,4 +63,74 @@ error:
> }
> EXPORT_SYMBOL(udp_sock_create);
>
> +struct udp_tunnel_sock *
> +create_udp_tunnel_sock(struct net *net, size_t size,
> + struct udp_tunnel_sock_cfg *cfg)
> +{
> + struct udp_tunnel_sock *uts;
> + struct sock *sk;
> + struct socket *sock = cfg->sock;
> +
> + uts = kzalloc(size, GFP_KERNEL);
> + if (!uts)
> + return ERR_PTR(-ENOMEM);
> +
> + sk = sock->sk;
> +
> + /* Disable multicast loopback */
> + inet_sk(sk)->mc_loop = 0;
> +
> + rcu_assign_sk_user_data(sk, uts);
> +
> + udp_sk(sk)->encap_type = cfg->encap_type;
> + udp_sk(sk)->encap_rcv = cfg->encap_rcv;
> + udp_sk(sk)->encap_destroy = cfg->encap_destroy;
> +
> + uts->sock = sock;
> +
> + udp_tunnel_encap_enable(sock);
> +
> + return uts;
> +}
> +EXPORT_SYMBOL_GPL(create_udp_tunnel_sock);
> +
> +int udp_tunnel_xmit_skb(struct udp_tunnel_sock *uts, struct rtable *rt,
> + struct sk_buff *skb, __be32 src, __be32 dst,
> + __u8 tos, __u8 ttl, __be16 df, __be16 src_port,
> + __be16 dst_port, bool xnet)
> +{
> + struct udphdr *uh;
> + struct socket *sock = uts->sock;
> +
> + __skb_push(skb, sizeof(*uh));
> + skb_reset_transport_header(skb);
> + uh = udp_hdr(skb);
> +
> + uh->dest = dst_port;
> + uh->source = src_port;
> + uh->len = htons(skb->len);
> +
> + udp_set_csum(sock->sk->sk_no_check_tx, skb, src, dst, skb->len);
> +
> + return iptunnel_xmit(sock->sk, rt, skb, src, dst, IPPROTO_UDP,
> + tos, ttl, df, xnet);
> +}
> +EXPORT_SYMBOL_GPL(udp_tunnel_xmit_skb);
> +
> +void udp_tunnel_sock_release(struct udp_tunnel_sock *uts)
> +{
> + struct sock *sk = uts->sock->sk;
> +
> + rcu_assign_sk_user_data(uts->sock->sk, NULL);
> + kernel_sock_shutdown(uts->sock, SHUT_RDWR);
> + sk_release_kernel(sk);
> +}
> +EXPORT_SYMBOL_GPL(udp_tunnel_sock_release);
> +
> +void udp_tunnel_sock_free(struct udp_tunnel_sock *uts)
> +{
> + kfree(uts);
> +}
> +EXPORT_SYMBOL_GPL(udp_tunnel_sock_free);
> +
> MODULE_LICENSE("GPL");
> diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile
> index 2fe6836..45f830e 100644
> --- a/net/ipv6/Makefile
> +++ b/net/ipv6/Makefile
> @@ -35,6 +35,7 @@ obj-$(CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION) += xfrm6_mode_ro.o
> obj-$(CONFIG_INET6_XFRM_MODE_BEET) += xfrm6_mode_beet.o
> obj-$(CONFIG_IPV6_MIP6) += mip6.o
> obj-$(CONFIG_NETFILTER) += netfilter/
> +obj-$(CONFIG_NET_UDP_TUNNEL) += ip6_udp_tunnel.o
>
> obj-$(CONFIG_IPV6_VTI) += ip6_vti.o
> obj-$(CONFIG_IPV6_SIT) += sit.o
> diff --git a/net/ipv6/ip6_udp_tunnel.c b/net/ipv6/ip6_udp_tunnel.c
> new file mode 100644
> index 0000000..5109f46
> --- /dev/null
> +++ b/net/ipv6/ip6_udp_tunnel.c
> @@ -0,0 +1,121 @@
> +#include <linux/module.h>
> +#include <linux/errno.h>
> +#include <linux/socket.h>
> +#include <linux/udp.h>
> +#include <linux/types.h>
> +#include <linux/kernel.h>
> +#include <linux/in6.h>
> +#include <net/udp.h>
> +#include <net/udp_tunnel.h>
> +#include <net/net_namespace.h>
> +#include <net/netns/generic.h>
> +#include <net/ip6_tunnel.h>
> +#include <net/ip6_checksum.h>
> +
> +int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg,
> + struct socket **sockp)
> +{
> + struct sockaddr_in6 udp6_addr;
> + int err = -EINVAL;
> + struct socket *sock = NULL;
> +
> + err = sock_create_kern(AF_INET6, SOCK_DGRAM, 0, &sock);
> + if (err < 0)
> + goto error;
> +
> + sk_change_net(sock->sk, net);
> +
> + udp6_addr.sin6_family = AF_INET6;
> + memcpy(&udp6_addr.sin6_addr, &cfg->local_ip6,
> + sizeof(udp6_addr.sin6_addr));
> + udp6_addr.sin6_port = cfg->local_udp_port;
> + err = kernel_bind(sock, (struct sockaddr *)&udp6_addr,
> + sizeof(udp6_addr));
> + if (err < 0)
> + goto error;
> +
> + if (cfg->peer_udp_port) {
> + udp6_addr.sin6_family = AF_INET6;
> + memcpy(&udp6_addr.sin6_addr, &cfg->peer_ip6,
> + sizeof(udp6_addr.sin6_addr));
> + udp6_addr.sin6_port = cfg->peer_udp_port;
> + err = kernel_connect(sock,
> + (struct sockaddr *)&udp6_addr,
> + sizeof(udp6_addr), 0);
> + }
> + if (err < 0)
> + goto error;
> +
> + udp_set_no_check6_tx(sock->sk, !cfg->use_udp6_tx_checksums);
> + udp_set_no_check6_rx(sock->sk, !cfg->use_udp6_rx_checksums);
> +
> + *sockp = sock;
> + return 0;
> +
> +error:
> + if (sock) {
> + kernel_sock_shutdown(sock, SHUT_RDWR);
> + sk_release_kernel(sock->sk);
> + }
> + *sockp = NULL;
> + return err;
> +}
> +EXPORT_SYMBOL_GPL(udp_sock_create6);
> +
> +int udp_tunnel6_xmit_skb(struct udp_tunnel_sock *uts, struct dst_entry *dst,
> + struct sk_buff *skb, struct net_device *dev,
> + struct in6_addr *saddr, struct in6_addr *daddr,
> + __u8 prio, __u8 ttl, __be16 src_port, __be16 dst_port)
> +{
> + struct udphdr *uh;
> + struct ipv6hdr *ip6h;
> +
> + __skb_push(skb, sizeof(*uh));
> + skb_reset_transport_header(skb);
> + uh = udp_hdr(skb);
> +
> + uh->dest = dst_port;
> + uh->source = src_port;
> +
> + uh->len = htons(skb->len);
> + uh->check = 0;
> +
> + memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
> + IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED
> + | IPSKB_REROUTED);
> + skb_dst_set(skb, dst);
> +
> + if (!skb_is_gso(skb) && !(dst->dev->features & NETIF_F_IPV6_CSUM)) {
> + __wsum csum = skb_checksum(skb, 0, skb->len, 0);
> +
> + skb->ip_summed = CHECKSUM_UNNECESSARY;
> + uh->check = csum_ipv6_magic(saddr, daddr, skb->len,
> + IPPROTO_UDP, csum);
> + if (uh->check == 0)
> + uh->check = CSUM_MANGLED_0;
> + } else {
> + skb->ip_summed = CHECKSUM_PARTIAL;
> + skb->csum_start = skb_transport_header(skb) - skb->head;
> + skb->csum_offset = offsetof(struct udphdr, check);
> + uh->check = ~csum_ipv6_magic(saddr, daddr,
> + skb->len, IPPROTO_UDP, 0);
> + }
> +
> + __skb_push(skb, sizeof(*ip6h));
> + skb_reset_network_header(skb);
> + ip6h = ipv6_hdr(skb);
> + ip6h->version = 6;
> + ip6h->priority = prio;
> + ip6h->flow_lbl[0] = 0;
> + ip6h->flow_lbl[1] = 0;
> + ip6h->flow_lbl[2] = 0;
Please call ip6_flow_hdr to set up flow label (see ip6_tnl_xmit2 for instance).
> + ip6h->payload_len = htons(skb->len);
> + ip6h->nexthdr = IPPROTO_UDP;
> + ip6h->hop_limit = ttl;
> + ip6h->daddr = *daddr;
> + ip6h->saddr = *saddr;
> +
> + ip6tunnel_xmit(skb, dev);
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(udp_tunnel6_xmit_skb);
> --
> 1.7.9.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v2 net] ipv6: clean up anycast when an interface is destroyed
From: David Miller @ 2014-09-12 21:33 UTC (permalink / raw)
To: sd; +Cc: cwang, netdev, hannes
In-Reply-To: <20140910212302.GA26184@kria>
From: Sabrina Dubroca <sd@queasysnail.net>
Date: Wed, 10 Sep 2014 23:23:02 +0200
> If we try to rmmod the driver for an interface while sockets with
> setsockopt(JOIN_ANYCAST) are alive, some refcounts aren't cleaned up
> and we get stuck on:
>
> unregister_netdevice: waiting for ens3 to become free. Usage count = 1
>
> If we LEAVE_ANYCAST/close everything before rmmod'ing, there is no
> problem.
>
> We need to perform a cleanup similar to the one for multicast in
> addrconf_ifdown(how == 1).
>
> Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
> ---
> v2: remove comment
Applied, thank you.
^ permalink raw reply
* Re: [net-next v5 1/3] udp-tunnel: Expand UDP tunnel APIs
From: Tom Herbert @ 2014-09-12 21:33 UTC (permalink / raw)
To: Andy Zhou; +Cc: David Miller, Linux Netdev List
In-Reply-To: <CACzMAJKn4zR8q1dQsiV4ShxbvamKYi2bCFrCyiVm-R8rM4Np2w@mail.gmail.com>
On Fri, Sep 12, 2014 at 1:42 PM, Andy Zhou <azhou@nicira.com> wrote:
> On Thu, Sep 11, 2014 at 2:04 PM, Tom Herbert <therbert@google.com> wrote:
>> On Wed, Sep 10, 2014 at 8:29 PM, Andy Zhou <azhou@nicira.com> wrote:
>>> Added common udp tunnel socket creation, and packet transmission APIs
>>> API that can be used by other UDP based tunneling protocol
>>> implementation.
>>>
>>> Signed-off-by: Andy Zhou <azhou@nicira.com>
>>> ---
>>> include/net/udp_tunnel.h | 73 +++++++++++++++++++++++++++
>>> net/ipv4/Kconfig | 1 +
>>> net/ipv4/udp_tunnel.c | 108 ++++++++++++++++++++++++++--------------
>>> net/ipv6/Makefile | 1 +
>>> net/ipv6/ip6_udp_tunnel.c | 121 +++++++++++++++++++++++++++++++++++++++++++++
>>> 5 files changed, 268 insertions(+), 36 deletions(-)
>>> create mode 100644 net/ipv6/ip6_udp_tunnel.c
>>>
>>> diff --git a/include/net/udp_tunnel.h b/include/net/udp_tunnel.h
>>> index ffd69cb..e9dcf83 100644
>>> --- a/include/net/udp_tunnel.h
>>> +++ b/include/net/udp_tunnel.h
>>> @@ -1,6 +1,14 @@
>>> #ifndef __NET_UDP_TUNNEL_H
>>> #define __NET_UDP_TUNNEL_H
>>>
>>> +#include <net/ip_tunnels.h>
>>> +#include <net/udp.h>
>>> +
>>> +#if IS_ENABLED(CONFIG_IPV6)
>>> +#include <net/ipv6.h>
>>> +#include <net/addrconf.h>
>>> +#endif
>>> +
>>> struct udp_port_cfg {
>>> u8 family;
>>>
>>> @@ -29,4 +37,69 @@ struct udp_port_cfg {
>>> int udp_sock_create(struct net *net, struct udp_port_cfg *cfg,
>>> struct socket **sockp);
>>>
>>> +#if IS_ENABLED(CONFIG_IPV6)
>>> +int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg,
>>> + struct socket **sockp);
>>> +#else
>>> +static inline int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg,
>>> + struct socket **sockp)
>>> +{
>>> + return 0;
>>> +}
>>> +#endif
>>> +
>>> +struct udp_tunnel_sock;
>>> +
>>> +typedef int (*udp_tunnel_encap_rcv_t)(struct sock *sk, struct sk_buff *skb);
>>> +typedef void (*udp_tunnel_encap_destroy_t)(struct sock *sk);
>>> +
>>> +struct udp_tunnel_sock_cfg {
>>> + struct socket *sock; /* The socket UDP tunnel will attach to */
>>> + /* Used for setting up udp_sock fields, see udp.h for details */
>>> + __u8 encap_type;
>>> + udp_tunnel_encap_rcv_t encap_rcv;
>>> + udp_tunnel_encap_destroy_t encap_destroy;
>>> +};
>>> +
>>> +struct udp_tunnel_sock {
>>> + struct socket *sock;
>>> +};
>>> +
>>> +struct udp_tunnel_sock *create_udp_tunnel_sock(struct net *net, size_t size,
>>> + struct udp_tunnel_sock_cfg
>>> + *sock_cfg);
>>> +
>>> +int udp_tunnel_xmit_skb(struct udp_tunnel_sock *uts, struct rtable *rt,
>>> + struct sk_buff *skb, __be32 src, __be32 dst,
>>> + __u8 tos, __u8 ttl, __be16 df, __be16 src_port,
>>> + __be16 dst_port, bool xnet);
>>> +
>>> +#if IS_ENABLED(CONFIG_IPV6)
>>> +int udp_tunnel6_xmit_skb(struct udp_tunnel_sock *uts, struct dst_entry *dst,
>>> + struct sk_buff *skb, struct net_device *dev,
>>> + struct in6_addr *saddr, struct in6_addr *daddr,
>>> + __u8 prio, __u8 ttl, __be16 src_port,
>>> + __be16 dst_port);
>>> +#endif
>>> +
>>> +void udp_tunnel_sock_release(struct udp_tunnel_sock *uts);
>>> +void udp_tunnel_sock_free(struct udp_tunnel_sock *uts);
>>> +
>>> +static inline struct sk_buff *udp_tunnel_handle_offloads(struct sk_buff *skb,
>>> + bool udp_csum)
>>> +{
>>> + int type = udp_csum ? SKB_GSO_UDP_TUNNEL_CSUM : SKB_GSO_UDP_TUNNEL;
>>> +
>>> + return iptunnel_handle_offloads(skb, udp_csum, type);
>>> +}
>>> +
>>> +static inline void udp_tunnel_encap_enable(struct socket *sock)
>>> +{
>>> +#if IS_ENABLED(CONFIG_IPV6)
>>> + if (sock->sk->sk_family == PF_INET6)
>>> + ipv6_stub->udpv6_encap_enable();
>>> + else
>>> +#endif
>>> + udp_encap_enable();
>>> +}
>>> #endif
>>> diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
>>> index dbc10d8..cccb95f 100644
>>> --- a/net/ipv4/Kconfig
>>> +++ b/net/ipv4/Kconfig
>>> @@ -308,6 +308,7 @@ config NET_IPVTI
>>> on top.
>>>
>>> config NET_UDP_TUNNEL
>>> + depends on (IPV6 || IPV6=n)
>>> tristate
>>> default n
>>>
>>> diff --git a/net/ipv4/udp_tunnel.c b/net/ipv4/udp_tunnel.c
>>> index 61ec1a6..d60c1a0 100644
>>> --- a/net/ipv4/udp_tunnel.c
>>> +++ b/net/ipv4/udp_tunnel.c
>>> @@ -14,42 +14,9 @@ int udp_sock_create(struct net *net, struct udp_port_cfg *cfg,
>>> int err = -EINVAL;
>>> struct socket *sock = NULL;
>>>
>>> -#if IS_ENABLED(CONFIG_IPV6)
>>> if (cfg->family == AF_INET6) {
>>> - struct sockaddr_in6 udp6_addr;
>>> -
>>> - err = sock_create_kern(AF_INET6, SOCK_DGRAM, 0, &sock);
>>> - if (err < 0)
>>> - goto error;
>>> -
>>> - sk_change_net(sock->sk, net);
>>> -
>>> - udp6_addr.sin6_family = AF_INET6;
>>> - memcpy(&udp6_addr.sin6_addr, &cfg->local_ip6,
>>> - sizeof(udp6_addr.sin6_addr));
>>> - udp6_addr.sin6_port = cfg->local_udp_port;
>>> - err = kernel_bind(sock, (struct sockaddr *)&udp6_addr,
>>> - sizeof(udp6_addr));
>>> - if (err < 0)
>>> - goto error;
>>> -
>>> - if (cfg->peer_udp_port) {
>>> - udp6_addr.sin6_family = AF_INET6;
>>> - memcpy(&udp6_addr.sin6_addr, &cfg->peer_ip6,
>>> - sizeof(udp6_addr.sin6_addr));
>>> - udp6_addr.sin6_port = cfg->peer_udp_port;
>>> - err = kernel_connect(sock,
>>> - (struct sockaddr *)&udp6_addr,
>>> - sizeof(udp6_addr), 0);
>>> - }
>>> - if (err < 0)
>>> - goto error;
>>> -
>>> - udp_set_no_check6_tx(sock->sk, !cfg->use_udp6_tx_checksums);
>>> - udp_set_no_check6_rx(sock->sk, !cfg->use_udp6_rx_checksums);
>>> - } else
>>> -#endif
>>> - if (cfg->family == AF_INET) {
>>> + return udp_sock_create6(net, cfg, sockp);
>>> + } else if (cfg->family == AF_INET) {
>>> struct sockaddr_in udp_addr;
>>>
>>> err = sock_create_kern(AF_INET, SOCK_DGRAM, 0, &sock);
>>> @@ -82,7 +49,6 @@ int udp_sock_create(struct net *net, struct udp_port_cfg *cfg,
>>> return -EPFNOSUPPORT;
>>> }
>>>
>>> -
>>> *sockp = sock;
>>>
>>> return 0;
>>> @@ -97,4 +63,74 @@ error:
>>> }
>>> EXPORT_SYMBOL(udp_sock_create);
>>>
>>> +struct udp_tunnel_sock *
>>> +create_udp_tunnel_sock(struct net *net, size_t size,
>>> + struct udp_tunnel_sock_cfg *cfg)
>>> +{
>>> + struct udp_tunnel_sock *uts;
>>> + struct sock *sk;
>>> + struct socket *sock = cfg->sock;
>>> +
>>> + uts = kzalloc(size, GFP_KERNEL);
>>> + if (!uts)
>>> + return ERR_PTR(-ENOMEM);
>>> +
>> Allocating memory for the caller seems like overkill to me and there's
>> no guarantee that is what caller wants anyway (maybe they are using
>> array of static structures for instance). Seems like it would be just
>> as easy to return the sock and let caller allocate whatever else it
>> needs on its own (only field in udp_tunnel_sock is the sock anyway).
> O.K. udp_tunnel layer does not need to allocate or maintain memory. It
> will further simplify this layer.
>>
>>> + sk = sock->sk;
>>> +
>>> + /* Disable multicast loopback */
>>> + inet_sk(sk)->mc_loop = 0;
>>> +
>> Probably want to enable checksum unnecessary conversions also.
> Right. Will do.
>>
>>> + rcu_assign_sk_user_data(sk, uts);
>>> +
>>> + udp_sk(sk)->encap_type = cfg->encap_type;
>>> + udp_sk(sk)->encap_rcv = cfg->encap_rcv;
>>> + udp_sk(sk)->encap_destroy = cfg->encap_destroy;
>>> +
>>> + uts->sock = sock;
>>> +
>>> + udp_tunnel_encap_enable(sock);
>>> +
>>> + return uts;
>>> +}
>>> +EXPORT_SYMBOL_GPL(create_udp_tunnel_sock);
>>> +
>>> +int udp_tunnel_xmit_skb(struct udp_tunnel_sock *uts, struct rtable *rt,
>>> + struct sk_buff *skb, __be32 src, __be32 dst,
>>> + __u8 tos, __u8 ttl, __be16 df, __be16 src_port,
>>> + __be16 dst_port, bool xnet)
>>> +{
>>> + struct udphdr *uh;
>>> + struct socket *sock = uts->sock;
>>> +
>>> + __skb_push(skb, sizeof(*uh));
>>> + skb_reset_transport_header(skb);
>>> + uh = udp_hdr(skb);
>>> +
>>> + uh->dest = dst_port;
>>> + uh->source = src_port;
>>> + uh->len = htons(skb->len);
>>> +
>>> + udp_set_csum(sock->sk->sk_no_check_tx, skb, src, dst, skb->len);
>>> +
>>> + return iptunnel_xmit(sock->sk, rt, skb, src, dst, IPPROTO_UDP,
>>> + tos, ttl, df, xnet);
>>> +}
>>> +EXPORT_SYMBOL_GPL(udp_tunnel_xmit_skb);
>>> +
>>> +void udp_tunnel_sock_release(struct udp_tunnel_sock *uts)
>>> +{
>>> + struct sock *sk = uts->sock->sk;
>>> +
>>> + rcu_assign_sk_user_data(uts->sock->sk, NULL);
>>> + kernel_sock_shutdown(uts->sock, SHUT_RDWR);
>>> + sk_release_kernel(sk);
>>> +}
>>> +EXPORT_SYMBOL_GPL(udp_tunnel_sock_release);
>>> +
>>> +void udp_tunnel_sock_free(struct udp_tunnel_sock *uts)
>>> +{
>>> + kfree(uts);
>>> +}
>>> +EXPORT_SYMBOL_GPL(udp_tunnel_sock_free);
>>> +
>>> MODULE_LICENSE("GPL");
>>> diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile
>>> index 2fe6836..45f830e 100644
>>> --- a/net/ipv6/Makefile
>>> +++ b/net/ipv6/Makefile
>>
>> Probably good to make IPv4 and v6 stuff in separate patches.
> Is this really necessary? Removing dependency may be tricky..
I suppose not, but if there are dependencies they should be from IPv6
to IPv4 files, not other way around.
>>
>>> @@ -35,6 +35,7 @@ obj-$(CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION) += xfrm6_mode_ro.o
>>> obj-$(CONFIG_INET6_XFRM_MODE_BEET) += xfrm6_mode_beet.o
>>> obj-$(CONFIG_IPV6_MIP6) += mip6.o
>>> obj-$(CONFIG_NETFILTER) += netfilter/
>>> +obj-$(CONFIG_NET_UDP_TUNNEL) += ip6_udp_tunnel.o
>>>
>>> obj-$(CONFIG_IPV6_VTI) += ip6_vti.o
>>> obj-$(CONFIG_IPV6_SIT) += sit.o
>>> diff --git a/net/ipv6/ip6_udp_tunnel.c b/net/ipv6/ip6_udp_tunnel.c
>>> new file mode 100644
>>> index 0000000..5109f46
>>> --- /dev/null
>>> +++ b/net/ipv6/ip6_udp_tunnel.c
>>> @@ -0,0 +1,121 @@
>>> +#include <linux/module.h>
>>> +#include <linux/errno.h>
>>> +#include <linux/socket.h>
>>> +#include <linux/udp.h>
>>> +#include <linux/types.h>
>>> +#include <linux/kernel.h>
>>> +#include <linux/in6.h>
>>> +#include <net/udp.h>
>>> +#include <net/udp_tunnel.h>
>>> +#include <net/net_namespace.h>
>>> +#include <net/netns/generic.h>
>>> +#include <net/ip6_tunnel.h>
>>> +#include <net/ip6_checksum.h>
>>> +
>>> +int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg,
>>> + struct socket **sockp)
>>> +{
>>> + struct sockaddr_in6 udp6_addr;
>>> + int err = -EINVAL;
>>> + struct socket *sock = NULL;
>>> +
>>> + err = sock_create_kern(AF_INET6, SOCK_DGRAM, 0, &sock);
>>> + if (err < 0)
>>> + goto error;
>>> +
>>> + sk_change_net(sock->sk, net);
>>> +
>>> + udp6_addr.sin6_family = AF_INET6;
>>> + memcpy(&udp6_addr.sin6_addr, &cfg->local_ip6,
>>> + sizeof(udp6_addr.sin6_addr));
>>> + udp6_addr.sin6_port = cfg->local_udp_port;
>>> + err = kernel_bind(sock, (struct sockaddr *)&udp6_addr,
>>> + sizeof(udp6_addr));
>>> + if (err < 0)
>>> + goto error;
>>> +
>>> + if (cfg->peer_udp_port) {
>>> + udp6_addr.sin6_family = AF_INET6;
>>> + memcpy(&udp6_addr.sin6_addr, &cfg->peer_ip6,
>>> + sizeof(udp6_addr.sin6_addr));
>>> + udp6_addr.sin6_port = cfg->peer_udp_port;
>>> + err = kernel_connect(sock,
>>> + (struct sockaddr *)&udp6_addr,
>>> + sizeof(udp6_addr), 0);
>>> + }
>>> + if (err < 0)
>>> + goto error;
>>> +
>>> + udp_set_no_check6_tx(sock->sk, !cfg->use_udp6_tx_checksums);
>>> + udp_set_no_check6_rx(sock->sk, !cfg->use_udp6_rx_checksums);
>>> +
>>> + *sockp = sock;
>>> + return 0;
>>> +
>>> +error:
>>> + if (sock) {
>>> + kernel_sock_shutdown(sock, SHUT_RDWR);
>>> + sk_release_kernel(sock->sk);
>>> + }
>>> + *sockp = NULL;
>>> + return err;
>>> +}
>>> +EXPORT_SYMBOL_GPL(udp_sock_create6);
>>> +
>>> +int udp_tunnel6_xmit_skb(struct udp_tunnel_sock *uts, struct dst_entry *dst,
>>> + struct sk_buff *skb, struct net_device *dev,
>>> + struct in6_addr *saddr, struct in6_addr *daddr,
>>> + __u8 prio, __u8 ttl, __be16 src_port, __be16 dst_port)
>>> +{
>>> + struct udphdr *uh;
>>> + struct ipv6hdr *ip6h;
>>> +
>>> + __skb_push(skb, sizeof(*uh));
>>> + skb_reset_transport_header(skb);
>>> + uh = udp_hdr(skb);
>>> +
>>> + uh->dest = dst_port;
>>> + uh->source = src_port;
>>> +
>>> + uh->len = htons(skb->len);
>>> + uh->check = 0;
>>> +
>>> + memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
>>> + IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED
>>> + | IPSKB_REROUTED);
>>> + skb_dst_set(skb, dst);
>>> +
>>> + if (!skb_is_gso(skb) && !(dst->dev->features & NETIF_F_IPV6_CSUM)) {
>>> + __wsum csum = skb_checksum(skb, 0, skb->len, 0);
>>> +
>>> + skb->ip_summed = CHECKSUM_UNNECESSARY;
>>> + uh->check = csum_ipv6_magic(saddr, daddr, skb->len,
>>> + IPPROTO_UDP, csum);
>>> + if (uh->check == 0)
>>> + uh->check = CSUM_MANGLED_0;
>>> + } else {
>>> + skb->ip_summed = CHECKSUM_PARTIAL;
>>> + skb->csum_start = skb_transport_header(skb) - skb->head;
>>> + skb->csum_offset = offsetof(struct udphdr, check);
>>> + uh->check = ~csum_ipv6_magic(saddr, daddr,
>>> + skb->len, IPPROTO_UDP, 0);
>>> + }
>>
>> Can't we call udp6_set_csum for this?
> Thanks for pointing it out. Will do.
>>
>>> +
>>> + __skb_push(skb, sizeof(*ip6h));
>>> + skb_reset_network_header(skb);
>>> + ip6h = ipv6_hdr(skb);
>>> + ip6h->version = 6;
>>> + ip6h->priority = prio;
>>> + ip6h->flow_lbl[0] = 0;
>>> + ip6h->flow_lbl[1] = 0;
>>> + ip6h->flow_lbl[2] = 0;
>>> + ip6h->payload_len = htons(skb->len);
>>> + ip6h->nexthdr = IPPROTO_UDP;
>>> + ip6h->hop_limit = ttl;
>>> + ip6h->daddr = *daddr;
>>> + ip6h->saddr = *saddr;
>>> +
>>> + ip6tunnel_xmit(skb, dev);
>>
>> So iptunnel_xmit creates the IP header, but ip6tunnel_xmit doesn't. It
>> should be on the TODO list to make this consistent!
> Agreed.
>>
>>> + return 0;
>>> +}
>>> +EXPORT_SYMBOL_GPL(udp_tunnel6_xmit_skb);
>>> --
>>> 1.7.9.5
>>>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe netdev" in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v2 0/2] net: arc_emac: fix tx issues
From: David Miller @ 2014-09-12 21:19 UTC (permalink / raw)
To: b.galvani
Cc: romain.perier, heiko, arnd, tklauser, jg1.han, max.schwarz,
f.fainelli, netdev, linux-kernel
In-Reply-To: <1410382203-10395-1-git-send-email-b.galvani@gmail.com>
From: Beniamino Galvani <b.galvani@gmail.com>
Date: Wed, 10 Sep 2014 22:50:01 +0200
> the patches below solve some issues found in the tx ring reclaim
> strategy currently implemented in the arc_emac driver.
>
> Without these patches a simple outgoing UDP flow blocks almost
> immediately with the socket send buffer full, until some new rx
> packets trigger a clean of the tx ring.
>
> Everything seems to work fine on a Radxa Rock with this fix applied.
Series applied, thanks.
^ permalink raw reply
* Re: [PATCH net-next 04/14] tipc: add sock dump to new netlink api
From: David Miller @ 2014-09-12 21:10 UTC (permalink / raw)
To: richard.alpe; +Cc: netdev, tipc-discussion
In-Reply-To: <1410424167-17427-5-git-send-email-richard.alpe@ericsson.com>
From: <richard.alpe@ericsson.com>
Date: Thu, 11 Sep 2014 10:29:17 +0200
> + list_for_each_entry_from(p, &tsk->publications, pport_list) {
> + publ = nla_nest_start(skb, TIPC_NLA_SOCK_PUBL);
> + if (nla_put_u32(skb, TIPC_NLA_PUBL_TYPE, p->type))
> + goto msg_full;
> + if (nla_put_u32(skb, TIPC_NLA_PUBL_LOWER, p->lower))
> + goto msg_full;
> + if (nla_put_u32(skb, TIPC_NLA_PUBL_UPPER, p->upper))
> + goto msg_full;
> + nla_nest_end(skb, publ);
> + }
> +
> + *prev_publ = 0;
> +
> + return 0;
> +
> +msg_full:
> + *prev_publ = p->key;
> + nla_nest_cancel(skb, publ);
This restart mechanism is broken.
You can't public nested information this way.
What happens in your code is that if we hit the limit in the middle of
adding the publications, the next time we'll put the same socket into
the netlink message and then the rest of the nested publications.
That's malformed.
You can't just say sometimes you'll partially list the set of nested
attributes in an object, you must public the entire object fully in
the netlink message or skip the object entirely.
I would suggest that you instead size the amount of space you'll
need for at least the first socket being listed, and if NLMSG_GOODSIZE
is insufficient, allocate as much as you will actually need.
Then you put full socket netlink blobs in there, including all nested
attributes, and then stop and reset back the the most recent full socket
published if you run out of space.
^ permalink raw reply
* Re: connect returns EADDRNOTAVAIL on ~600k+ sockets host
From: Denys Fedoryshchenko @ 2014-09-12 21:09 UTC (permalink / raw)
To: netdev
In-Reply-To: <d9db14adbac97234729b112ebfa87c91@visp.net.lb>
After some "printk" debugging, also found additional information,
error is returned in __inet_hash_connect, as i understand because it
can't find
free local port.
But i dont think correct, that on such loaded server basic
socket/connect sequence will not work, while there is for sure free
ports on ips used for outgoing connection.
On 2014-09-12 21:18, Denys Fedoryshchenko wrote:
> Hi
>
> I noticed strange behaviour on loaded server (haproxy), while it is
> handling load for https traffic well, tcp monitoring started to give
> false alerts. And here what i found:
>
> HTTPS-BALANCER ~ # telnet 127.0.0.1 23
> telnet: can't connect to remote host (127.0.0.1): Cannot assign
> requested address
> HTTPS-BALANCER ~ # nc -v 127.0.0.1 23
> 127.0.0.1 (127.0.0.1:23) open
> ��\x01��\x1f��\x01��\x03
> HTTPS-BALANCER login: ^Cpunt!
>
> The difference is (relevant lines from strace):
>
> socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3
> setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
> bind(3, {sa_family=AF_INET, sin_port=htons(0),
> sin_addr=inet_addr("0.0.0.0")}, 16) = 0
> rt_sigaction(SIGALRM, {0x41ecfb, [ALRM], SA_RESTORER|SA_RESTART,
> 0x7f80725bf5b0}, {SIG_DFL, [], 0}, 8) = 0
> alarm(0) = 0
> connect(3, {sa_family=AF_INET, sin_port=htons(23),
> sin_addr=inet_addr("127.0.0.1")}, 16) = 0
> rt_sigaction(SIGALRM, {SIG_IGN, [ALRM], SA_RESTORER|SA_RESTART,
> 0x7f80725bf5b0}, {0x41ecfb, [ALRM], SA_RESTORER|SA_RESTART, 0x7
>
>
> socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3
> setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
> connect(3, {sa_family=AF_INET, sin_port=htons(23),
> sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EADDRNOTAVAIL (Cannot
> assign requested address)
> write(2, "telnet: can't connect to remote host (127.0.0.1): Cannot
> assign requested address\n", 82telnet: can't connect to remote host
> (127.0.0.1): Cannot assign requested address
>
> So,
> bind(3, {sa_family=AF_INET, sin_port=htons(0),
> sin_addr=inet_addr("0.0.0.0")}, 16) = 0
> is fixing issue, but is it really supposed to be like this?
>
> Just for information host load and some network stats:
> from /proc/net/protocols, i removed irrelevant zero values entries
>
> protocol size sockets memory press maxhdr slab module cl co di
> ac io in de sh ss gs se re sp bi br ha uh gp em
> UDP 816 1 0 NI 0 yes kernel y y y
> n y n y n y y y y y n y y y y n
> TCP 1640 728255 751777 no 208 yes kernel y y y
> y y y y y y y y y y n y y y y y
>
> sockets: used 674375
> TCP: inuse 727092 orphan 55119 tw 138533 alloc 729419 mem 745187
> UDP: inuse 1 mem 0
> UDPLITE: inuse 0
> RAW: inuse 0
> FRAG: inuse 0 memory 0
>
> 0.0.0.0 sockets:
> tcp 0 0 0.0.0.0:65530 0.0.0.0:*
> LISTEN
> tcp 0 0 0.0.0.0:443 0.0.0.0:*
> LISTEN
> tcp 0 0 0.0.0.0:8880 0.0.0.0:*
> LISTEN
> tcp 0 0 0.0.0.0:22 0.0.0.0:*
> LISTEN
> tcp 0 0 0.0.0.0:23 0.0.0.0:*
> LISTEN
> udp 0 0 0.0.0.0:53073 0.0.0.0:*
>
> 127.0.0.1 sockets (this is watchdog, but if i disable, it wont change
> anything)
> tcp 0 0 127.0.0.1:65530 127.0.0.1:55649
> TIME_WAIT
> tcp 0 0 127.0.0.1:65530 127.0.0.1:41762
> FIN_WAIT2
> tcp 0 0 127.0.0.1:65530 127.0.0.1:36863
> TIME_WAIT
> tcp 0 0 127.0.0.1:65530 127.0.0.1:34533
> TIME_WAIT
> tcp 0 0 127.0.0.1:65530 127.0.0.1:35262
> TIME_WAIT
> tcp 0 0 127.0.0.1:65530 127.0.0.1:45872
> TIME_WAIT
^ permalink raw reply
* Re: [PATCH net-next 01/14] tipc: add bearer disable/enable to new netlink api
From: David Miller @ 2014-09-12 21:07 UTC (permalink / raw)
To: richard.alpe; +Cc: netdev, tipc-discussion
In-Reply-To: <1410424167-17427-2-git-send-email-richard.alpe@ericsson.com>
From: <richard.alpe@ericsson.com>
Date: Thu, 11 Sep 2014 10:29:14 +0200
> +struct tipc_nl_msg {
> + struct sk_buff *skb;
> + u32 portid;
> + u32 seq;
> +};
This datastructure has no users this early in the patch series. Add it to the
patch which actually has a user.
^ permalink raw reply
* [Patch v4 net-next 12/12] ARM: dts: imx6sx: add multi-queue support enet
From: Frank.Li @ 2014-09-12 21:00 UTC (permalink / raw)
To: b38611, davem, netdev, lznuaa
Cc: Frank Li, devicetree, shawn.guo, linux, linux-arm-kernel
In-Reply-To: <1410555657-10744-1-git-send-email-Frank.Li@freescale.com>
From: Frank Li <Frank.Li@freescale.com>
Enable 3 queues suppport for ethernet
Signed-off-by: Frank Li <Frank.Li@freescale.com>
---
arch/arm/boot/dts/imx6sx.dtsi | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi
index f4b9da6..0a03260 100644
--- a/arch/arm/boot/dts/imx6sx.dtsi
+++ b/arch/arm/boot/dts/imx6sx.dtsi
@@ -776,6 +776,8 @@
<&clks IMX6SX_CLK_ENET_PTP>;
clock-names = "ipg", "ahb", "ptp",
"enet_clk_ref", "enet_out";
+ fsl,num-tx-queues=<3>;
+ fsl,num-rx-queues=<3>;
status = "disabled";
};
--
1.9.1
^ permalink raw reply related
* [Patch v4 net-next 09/12] net: fec: change FEC alignment according to i.mx6 sx requirement
From: Frank.Li @ 2014-09-12 21:00 UTC (permalink / raw)
To: b38611, davem, netdev, lznuaa
Cc: devicetree, Frank Li, Fugang Duan, linux, shawn.guo,
linux-arm-kernel
In-Reply-To: <1410555657-10744-1-git-send-email-Frank.Li@freescale.com>
From: Fugang Duan <B38611@freescale.com>
i.MX6 SX change FEC alignment requirement.
i.MX6 SX change internal bus from AHB to AXI.
It require RX buffer must be 64 bytes alignment.
And remove TX buffer alignment requirement.
Signed-off-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Frank Li <Frank.Li@freescale.com>
---
drivers/net/ethernet/freescale/fec.h | 3 +++
drivers/net/ethernet/freescale/fec_main.c | 35 +++++++++++++++++++++----------
2 files changed, 27 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index 5ec3828..b7c7722 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -443,6 +443,9 @@ struct fec_enet_private {
int hwts_tx_en;
struct delayed_work time_keep;
struct regulator *reg_phy;
+
+ unsigned int tx_align;
+ unsigned int rx_align;
};
void fec_ptp_init(struct platform_device *pdev);
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 0cc7313..9840a10 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -64,12 +64,6 @@
static void set_multicast_list(struct net_device *ndev);
-#if defined(CONFIG_ARM)
-#define FEC_ALIGNMENT 0xf
-#else
-#define FEC_ALIGNMENT 0x3
-#endif
-
#define DRIVER_NAME "fec"
#define FEC_ENET_GET_QUQUE(_x) ((_x == 0) ? 1 : ((_x == 1) ? 2 : 0))
@@ -434,7 +428,7 @@ fec_enet_txq_submit_frag_skb(struct fec_enet_priv_tx_q *txq,
bufaddr = page_address(this_frag->page.p) + this_frag->page_offset;
index = fec_enet_get_bd_index(txq->tx_bd_base, bdp, fep);
- if (((unsigned long) bufaddr) & FEC_ALIGNMENT ||
+ if (((unsigned long) bufaddr) & fep->tx_align ||
id_entry->driver_data & FEC_QUIRK_SWAP_FRAME) {
memcpy(txq->tx_bounce[index], bufaddr, frag_len);
bufaddr = txq->tx_bounce[index];
@@ -514,7 +508,7 @@ static int fec_enet_txq_submit_skb(struct fec_enet_priv_tx_q *txq,
queue = skb_get_queue_mapping(skb);
index = fec_enet_get_bd_index(txq->tx_bd_base, bdp, fep);
- if (((unsigned long) bufaddr) & FEC_ALIGNMENT ||
+ if (((unsigned long) bufaddr) & fep->tx_align ||
id_entry->driver_data & FEC_QUIRK_SWAP_FRAME) {
memcpy(txq->tx_bounce[index], skb->data, buflen);
bufaddr = txq->tx_bounce[index];
@@ -607,7 +601,7 @@ fec_enet_txq_put_data_tso(struct fec_enet_priv_tx_q *txq, struct sk_buff *skb,
status |= (BD_ENET_TX_TC | BD_ENET_TX_READY);
- if (((unsigned long) data) & FEC_ALIGNMENT ||
+ if (((unsigned long) data) & fep->tx_align ||
id_entry->driver_data & FEC_QUIRK_SWAP_FRAME) {
memcpy(txq->tx_bounce[index], data, size);
data = txq->tx_bounce[index];
@@ -669,7 +663,7 @@ fec_enet_txq_put_hdr_tso(struct fec_enet_priv_tx_q *txq,
bufaddr = txq->tso_hdrs + index * TSO_HEADER_SIZE;
dmabuf = txq->tso_hdrs_dma + index * TSO_HEADER_SIZE;
- if (((unsigned long) bufaddr) & FEC_ALIGNMENT ||
+ if (((unsigned long)bufaddr) & fep->tx_align ||
id_entry->driver_data & FEC_QUIRK_SWAP_FRAME) {
memcpy(txq->tx_bounce[index], skb->data, hdr_len);
bufaddr = txq->tx_bounce[index];
@@ -2399,6 +2393,7 @@ fec_enet_alloc_rxq_buffers(struct net_device *ndev, unsigned int queue)
struct sk_buff *skb;
struct bufdesc *bdp;
struct fec_enet_priv_rx_q *rxq;
+ unsigned int off;
rxq = fep->rx_queue[queue];
bdp = rxq->rx_bd_base;
@@ -2409,8 +2404,13 @@ fec_enet_alloc_rxq_buffers(struct net_device *ndev, unsigned int queue)
if (!skb)
goto err_alloc;
+ off = ((unsigned long)skb->data) & fep->rx_align;
+ if (off)
+ skb_reserve(skb, fep->rx_align + 1 - off);
+
addr = dma_map_single(&fep->pdev->dev, skb->data,
- FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE);
+ FEC_ENET_RX_FRSIZE - fep->rx_align, DMA_FROM_DEVICE);
+
if (dma_mapping_error(&fep->pdev->dev, addr)) {
dev_kfree_skb(skb);
if (net_ratelimit())
@@ -2743,6 +2743,14 @@ static int fec_enet_init(struct net_device *ndev)
int bd_size;
unsigned int i;
+#if defined(CONFIG_ARM)
+ fep->rx_align = 0xf;
+ fep->tx_align = 0xf;
+#else
+ fep->rx_align = 0x3;
+ fep->tx_align = 0x3;
+#endif
+
fec_enet_alloc_queue(ndev);
if (fep->bufdesc_ex)
@@ -2819,6 +2827,11 @@ static int fec_enet_init(struct net_device *ndev)
fep->csum_flags |= FLAG_RX_CSUM_ENABLED;
}
+ if (id_entry->driver_data & FEC_QUIRK_HAS_AVB) {
+ fep->tx_align = 0;
+ fep->rx_align = 0x3f;
+ }
+
ndev->hw_features = ndev->features;
fec_restart(ndev);
--
1.9.1
^ permalink raw reply related
* [Patch v4 net-next 08/12] net:fec: Add fsl, imx6sx-fec compatible strings
From: Frank.Li @ 2014-09-12 21:00 UTC (permalink / raw)
To: b38611, davem, netdev, lznuaa
Cc: devicetree, Frank Li, Fugang Duan, linux, shawn.guo,
linux-arm-kernel
In-Reply-To: <1410555657-10744-1-git-send-email-Frank.Li@freescale.com>
From: Fugang Duan <B38611@freescale.com>
Add compatible string "fsl,imx6sx-fec" for i.MX6SX.
Signed-off-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Frank Li <Frank.Li@freescale.com>
---
drivers/net/ethernet/freescale/fec_main.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 658b0b3..0cc7313 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -157,6 +157,7 @@ enum imx_fec_type {
IMX28_FEC,
IMX6Q_FEC,
MVF600_FEC,
+ IMX6SX_FEC,
};
static const struct of_device_id fec_dt_ids[] = {
@@ -165,6 +166,7 @@ static const struct of_device_id fec_dt_ids[] = {
{ .compatible = "fsl,imx28-fec", .data = &fec_devtype[IMX28_FEC], },
{ .compatible = "fsl,imx6q-fec", .data = &fec_devtype[IMX6Q_FEC], },
{ .compatible = "fsl,mvf600-fec", .data = &fec_devtype[MVF600_FEC], },
+ { .compatible = "fsl,imx6sx-fec", .data = &fec_devtype[IMX6SX_FEC], },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, fec_dt_ids);
--
1.9.1
^ permalink raw reply related
* [Patch v4 net-next 07/12] net: fec: add enet-avb IP support
From: Frank.Li @ 2014-09-12 21:00 UTC (permalink / raw)
To: b38611, davem, netdev, lznuaa
Cc: devicetree, Frank Li, Fugang Duan, linux, shawn.guo,
linux-arm-kernel
In-Reply-To: <1410555657-10744-1-git-send-email-Frank.Li@freescale.com>
From: Frank Li <Frank.Li@freescale.com>
i.MX6SX Enet-AVB support 3 tx queues, 3 rx queues.
For tx queues: ring 0 -> best effort
ring 1 -> Class A
ring 2 -> Class B
For rx queues:
ring 0 -> best effort
ring 1 -> receive VLAN packet with classification match
ring 2 -> receive VLAN packet with classification match
Add enet-avb IP multiqueue support for the driver.
Signed-off-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Frank Li <Frank.Li@freescale.com>
---
drivers/net/ethernet/freescale/fec.h | 33 ++++++++++++++++++++++++++++
drivers/net/ethernet/freescale/fec_main.c | 36 +++++++++++++++----------------
2 files changed, 51 insertions(+), 18 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index 72fb90f..5ec3828 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -38,6 +38,12 @@
#define FEC_ADDR_LOW 0x0e4 /* Low 32bits MAC address */
#define FEC_ADDR_HIGH 0x0e8 /* High 16bits MAC address */
#define FEC_OPD 0x0ec /* Opcode + Pause duration */
+#define FEC_TXIC0 0xF0 /* Tx Interrupt Coalescing for ring 0 */
+#define FEC_TXIC1 0xF4 /* Tx Interrupt Coalescing for ring 1 */
+#define FEC_TXIC2 0xF8 /* Tx Interrupt Coalescing for ring 2 */
+#define FEC_RXIC0 0x100 /* Rx Interrupt Coalescing for ring 0 */
+#define FEC_RXIC1 0x104 /* Rx Interrupt Coalescing for ring 1 */
+#define FEC_RXIC2 0x108 /* Rx Interrupt Coalescing for ring 2 */
#define FEC_HASH_TABLE_HIGH 0x118 /* High 32bits hash table */
#define FEC_HASH_TABLE_LOW 0x11c /* Low 32bits hash table */
#define FEC_GRP_HASH_TABLE_HIGH 0x120 /* High 32bits hash table */
@@ -65,6 +71,7 @@
#define FEC_X_DES_ACTIVE_1 0x1e4 /* Tx descriptor active for ring 1 */
#define FEC_R_DES_ACTIVE_2 0x1e8 /* Rx descriptor active for ring 2 */
#define FEC_X_DES_ACTIVE_2 0x1ec /* Tx descriptor active for ring 2 */
+#define FEC_QOS_SCHEME 0x1f0 /* Set multi queues Qos scheme */
#define FEC_MIIGSK_CFGR 0x300 /* MIIGSK Configuration reg */
#define FEC_MIIGSK_ENR 0x308 /* MIIGSK Enable reg */
@@ -305,6 +312,32 @@ struct bufdesc_ex {
#define FLAG_RX_CSUM_ENABLED (BD_ENET_RX_ICE | BD_ENET_RX_PCR)
#define FLAG_RX_CSUM_ERROR (BD_ENET_RX_ICE | BD_ENET_RX_PCR)
+/* Interrupt events/masks. */
+#define FEC_ENET_HBERR ((uint)0x80000000) /* Heartbeat error */
+#define FEC_ENET_BABR ((uint)0x40000000) /* Babbling receiver */
+#define FEC_ENET_BABT ((uint)0x20000000) /* Babbling transmitter */
+#define FEC_ENET_GRA ((uint)0x10000000) /* Graceful stop complete */
+#define FEC_ENET_TXF_0 ((uint)0x08000000) /* Full frame transmitted */
+#define FEC_ENET_TXF_1 ((uint)0x00000008) /* Full frame transmitted */
+#define FEC_ENET_TXF_2 ((uint)0x00000080) /* Full frame transmitted */
+#define FEC_ENET_TXB ((uint)0x04000000) /* A buffer was transmitted */
+#define FEC_ENET_RXF_0 ((uint)0x02000000) /* Full frame received */
+#define FEC_ENET_RXF_1 ((uint)0x00000002) /* Full frame received */
+#define FEC_ENET_RXF_2 ((uint)0x00000020) /* Full frame received */
+#define FEC_ENET_RXB ((uint)0x01000000) /* A buffer was received */
+#define FEC_ENET_MII ((uint)0x00800000) /* MII interrupt */
+#define FEC_ENET_EBERR ((uint)0x00400000) /* SDMA bus error */
+#define FEC_ENET_TXF (FEC_ENET_TXF_0 | FEC_ENET_TXF_1 | FEC_ENET_TXF_2)
+#define FEC_ENET_RXF (FEC_ENET_RXF_0 | FEC_ENET_RXF_1 | FEC_ENET_RXF_2)
+#define FEC_ENET_TS_AVAIL ((uint)0x00010000)
+#define FEC_ENET_TS_TIMER ((uint)0x00008000)
+
+#define FEC_DEFAULT_IMASK (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII | FEC_ENET_TS_TIMER)
+#define FEC_RX_DISABLED_IMASK (FEC_DEFAULT_IMASK & (~FEC_ENET_RXF))
+
+#define FEC_VLAN_TAG_LEN 0x04
+#define FEC_ETHTYPE_LEN 0x02
+
struct fec_enet_priv_tx_q {
int index;
unsigned char *tx_bounce[TX_RING_SIZE];
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 5f8e997..658b0b3 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -193,21 +193,6 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
#endif
#endif /* CONFIG_M5272 */
-/* Interrupt events/masks. */
-#define FEC_ENET_HBERR ((uint)0x80000000) /* Heartbeat error */
-#define FEC_ENET_BABR ((uint)0x40000000) /* Babbling receiver */
-#define FEC_ENET_BABT ((uint)0x20000000) /* Babbling transmitter */
-#define FEC_ENET_GRA ((uint)0x10000000) /* Graceful stop complete */
-#define FEC_ENET_TXF ((uint)0x08000000) /* Full frame transmitted */
-#define FEC_ENET_TXB ((uint)0x04000000) /* A buffer was transmitted */
-#define FEC_ENET_RXF ((uint)0x02000000) /* Full frame received */
-#define FEC_ENET_RXB ((uint)0x01000000) /* A buffer was received */
-#define FEC_ENET_MII ((uint)0x00800000) /* MII interrupt */
-#define FEC_ENET_EBERR ((uint)0x00400000) /* SDMA bus error */
-
-#define FEC_DEFAULT_IMASK (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII)
-#define FEC_RX_DISABLED_IMASK (FEC_DEFAULT_IMASK & (~FEC_ENET_RXF))
-
/* The FEC stores dest/src/type/vlan, data, and checksum for receive packets.
*/
#define PKT_MAXBUF_SIZE 1522
@@ -882,6 +867,15 @@ static void fec_enet_bd_init(struct net_device *dev)
}
}
+static void fec_enet_active_rxring(struct net_device *ndev)
+{
+ struct fec_enet_private *fep = netdev_priv(ndev);
+ int i;
+
+ for (i = 0; i < fep->num_rx_queues; i++)
+ writel(0, fep->hwp + FEC_R_DES_ACTIVE(i));
+}
+
static void fec_enet_enable_ring(struct net_device *ndev)
{
struct fec_enet_private *fep = netdev_priv(ndev);
@@ -939,7 +933,6 @@ fec_restart(struct net_device *ndev)
struct fec_enet_private *fep = netdev_priv(ndev);
const struct platform_device_id *id_entry =
platform_get_device_id(fep->pdev);
- int i;
u32 val;
u32 temp_mac[2];
u32 rcntl = OPT_FRAME_SIZE | 0x04;
@@ -1099,8 +1092,7 @@ fec_restart(struct net_device *ndev)
/* And last, enable the transmit and receive processing */
writel(ecntl, fep->hwp + FEC_ECNTRL);
- for (i = 0; i < fep->num_rx_queues; i++)
- writel(0, fep->hwp + FEC_R_DES_ACTIVE(i));
+ fec_enet_active_rxring(ndev);
if (fep->bufdesc_ex)
fec_ptp_start_cyclecounter(ndev);
@@ -1511,9 +1503,17 @@ fec_enet_collect_events(struct fec_enet_private *fep, uint int_events)
if (int_events & FEC_ENET_RXF)
fep->work_rx |= (1 << 2);
+ if (int_events & FEC_ENET_RXF_1)
+ fep->work_rx |= (1 << 0);
+ if (int_events & FEC_ENET_RXF_2)
+ fep->work_rx |= (1 << 1);
if (int_events & FEC_ENET_TXF)
fep->work_tx |= (1 << 2);
+ if (int_events & FEC_ENET_TXF_1)
+ fep->work_tx |= (1 << 0);
+ if (int_events & FEC_ENET_TXF_2)
+ fep->work_tx |= (1 << 1);
return true;
}
--
1.9.1
^ permalink raw reply related
* [Patch v4 net-next 06/12] net:fec: Disable enet-avb MAC instead of reset MAC
From: Frank.Li @ 2014-09-12 21:00 UTC (permalink / raw)
To: b38611, davem, netdev, lznuaa
Cc: devicetree, Frank Li, Fugang Duan, linux, shawn.guo,
linux-arm-kernel
In-Reply-To: <1410555657-10744-1-git-send-email-Frank.Li@freescale.com>
From: Fugang Duan <B38611@freescale.com>
For i.MX6SX enet use AXI bus, reset MAC will make system bus dead
if ENET-AXI bus has pending access (AHB bus should not have such issue).
So, disable enet with AVB MAC instead of reset MAC itself.
Signed-off-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Frank Li <Frank.Li@freescale.com>
---
drivers/net/ethernet/freescale/fec_main.c | 26 ++++++++++++++++++++------
1 file changed, 20 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 03972f7..5f8e997 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -945,9 +945,16 @@ fec_restart(struct net_device *ndev)
u32 rcntl = OPT_FRAME_SIZE | 0x04;
u32 ecntl = 0x2; /* ETHEREN */
- /* Whack a reset. We should wait for this. */
- writel(1, fep->hwp + FEC_ECNTRL);
- udelay(10);
+ /* Whack a reset. We should wait for this.
+ * For i.MX6SX SOC, enet use AXI bus, we use disable MAC
+ * instead of reset MAC itself.
+ */
+ if (id_entry && id_entry->driver_data & FEC_QUIRK_HAS_AVB) {
+ writel(0, fep->hwp + FEC_ECNTRL);
+ } else {
+ writel(1, fep->hwp + FEC_ECNTRL);
+ udelay(10);
+ }
/*
* enet-mac reset will reset mac address registers too,
@@ -1118,9 +1125,16 @@ fec_stop(struct net_device *ndev)
netdev_err(ndev, "Graceful transmit stop did not complete!\n");
}
- /* Whack a reset. We should wait for this. */
- writel(1, fep->hwp + FEC_ECNTRL);
- udelay(10);
+ /* Whack a reset. We should wait for this.
+ * For i.MX6SX SOC, enet use AXI bus, we use disable MAC
+ * instead of reset MAC itself.
+ */
+ if (id_entry && id_entry->driver_data & FEC_QUIRK_HAS_AVB) {
+ writel(0, fep->hwp + FEC_ECNTRL);
+ } else {
+ writel(1, fep->hwp + FEC_ECNTRL);
+ udelay(10);
+ }
writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
--
1.9.1
^ permalink raw reply related
* [Patch v4 net-next 05/12] net: fec: init multi queue date structure
From: Frank.Li @ 2014-09-12 21:00 UTC (permalink / raw)
To: b38611, davem, netdev, lznuaa
Cc: devicetree, Frank Li, Duan Fugang, linux, shawn.guo,
linux-arm-kernel
In-Reply-To: <1410555657-10744-1-git-send-email-Frank.Li@freescale.com>
From: Frank Li <Frank.Li@freescale.com>
initilized all queues according to queue number get from DT file.
Signed-off-by: Frank Li <Frank.Li@freescale.com>
Signed-off-by: Duan Fugang <B38611@freescale.com>
---
drivers/net/ethernet/freescale/fec_main.c | 365 +++++++++++++++++++++---------
1 file changed, 252 insertions(+), 113 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 2240df0..03972f7 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -834,47 +834,98 @@ static void fec_enet_bd_init(struct net_device *dev)
struct fec_enet_priv_rx_q *rxq;
struct bufdesc *bdp;
unsigned int i;
+ unsigned int q;
- /* Initialize the receive buffer descriptors. */
- rxq = fep->rx_queue[0];
- bdp = rxq->rx_bd_base;
+ for (q = 0; q < fep->num_rx_queues; q++) {
+ /* Initialize the receive buffer descriptors. */
+ rxq = fep->rx_queue[q];
+ bdp = rxq->rx_bd_base;
- for (i = 0; i < rxq->rx_ring_size; i++) {
+ for (i = 0; i < rxq->rx_ring_size; i++) {
- /* Initialize the BD for every fragment in the page. */
- if (bdp->cbd_bufaddr)
- bdp->cbd_sc = BD_ENET_RX_EMPTY;
- else
+ /* Initialize the BD for every fragment in the page. */
+ if (bdp->cbd_bufaddr)
+ bdp->cbd_sc = BD_ENET_RX_EMPTY;
+ else
+ bdp->cbd_sc = 0;
+ bdp = fec_enet_get_nextdesc(bdp, fep, q);
+ }
+
+ /* Set the last buffer to wrap */
+ bdp = fec_enet_get_prevdesc(bdp, fep, q);
+ bdp->cbd_sc |= BD_SC_WRAP;
+
+ rxq->cur_rx = rxq->rx_bd_base;
+ }
+
+ for (q = 0; q < fep->num_tx_queues; q++) {
+ /* ...and the same for transmit */
+ txq = fep->tx_queue[q];
+ bdp = txq->tx_bd_base;
+ txq->cur_tx = bdp;
+
+ for (i = 0; i < txq->tx_ring_size; i++) {
+ /* Initialize the BD for every fragment in the page. */
bdp->cbd_sc = 0;
- bdp = fec_enet_get_nextdesc(bdp, fep, 0);
+ if (txq->tx_skbuff[i]) {
+ dev_kfree_skb_any(txq->tx_skbuff[i]);
+ txq->tx_skbuff[i] = NULL;
+ }
+ bdp->cbd_bufaddr = 0;
+ bdp = fec_enet_get_nextdesc(bdp, fep, q);
+ }
+
+ /* Set the last buffer to wrap */
+ bdp = fec_enet_get_prevdesc(bdp, fep, q);
+ bdp->cbd_sc |= BD_SC_WRAP;
+ txq->dirty_tx = bdp;
}
+}
- /* Set the last buffer to wrap */
- bdp = fec_enet_get_prevdesc(bdp, fep, 0);
- bdp->cbd_sc |= BD_SC_WRAP;
+static void fec_enet_enable_ring(struct net_device *ndev)
+{
+ struct fec_enet_private *fep = netdev_priv(ndev);
+ struct fec_enet_priv_tx_q *txq;
+ struct fec_enet_priv_rx_q *rxq;
+ int i;
- rxq->cur_rx = rxq->rx_bd_base;
+ for (i = 0; i < fep->num_rx_queues; i++) {
+ rxq = fep->rx_queue[i];
+ writel(rxq->bd_dma, fep->hwp + FEC_R_DES_START(i));
- /* ...and the same for transmit */
- txq = fep->tx_queue[0];
- bdp = txq->tx_bd_base;
- txq->cur_tx = bdp;
+ /* enable DMA1/2 */
+ if (i)
+ writel(RCMR_MATCHEN | RCMR_CMP(i),
+ fep->hwp + FEC_RCMR(i));
+ }
- for (i = 0; i < txq->tx_ring_size; i++) {
- /* Initialize the BD for every fragment in the page. */
- bdp->cbd_sc = 0;
- if (txq->tx_skbuff[i]) {
- dev_kfree_skb_any(txq->tx_skbuff[i]);
- txq->tx_skbuff[i] = NULL;
- }
- bdp->cbd_bufaddr = 0;
- bdp = fec_enet_get_nextdesc(bdp, fep, 0);
+ for (i = 0; i < fep->num_tx_queues; i++) {
+ txq = fep->tx_queue[i];
+ writel(txq->bd_dma, fep->hwp + FEC_X_DES_START(i));
+
+ /* enable DMA1/2 */
+ if (i)
+ writel(DMA_CLASS_EN | IDLE_SLOPE(i),
+ fep->hwp + FEC_DMA_CFG(i));
}
+}
- /* Set the last buffer to wrap */
- bdp = fec_enet_get_prevdesc(bdp, fep, 0);
- bdp->cbd_sc |= BD_SC_WRAP;
- txq->dirty_tx = bdp;
+static void fec_enet_reset_skb(struct net_device *ndev)
+{
+ struct fec_enet_private *fep = netdev_priv(ndev);
+ struct fec_enet_priv_tx_q *txq;
+ int i, j;
+
+ for (i = 0; i < fep->num_tx_queues; i++) {
+ txq = fep->tx_queue[i];
+
+ for (j = 0; j < txq->tx_ring_size; j++) {
+ if (txq->tx_skbuff[j]) {
+ dev_kfree_skb_any(txq->tx_skbuff[j]);
+ txq->tx_skbuff[j] = NULL;
+ }
+ }
+ }
}
/*
@@ -893,8 +944,6 @@ fec_restart(struct net_device *ndev)
u32 temp_mac[2];
u32 rcntl = OPT_FRAME_SIZE | 0x04;
u32 ecntl = 0x2; /* ETHEREN */
- struct fec_enet_priv_tx_q *txq;
- struct fec_enet_priv_rx_q *rxq;
/* Whack a reset. We should wait for this. */
writel(1, fep->hwp + FEC_ECNTRL);
@@ -918,24 +967,10 @@ fec_restart(struct net_device *ndev)
fec_enet_bd_init(ndev);
- /* Set receive and transmit descriptor base. */
- rxq = fep->rx_queue[0];
- writel(rxq->bd_dma, fep->hwp + FEC_R_DES_START(0));
- if (fep->bufdesc_ex)
- writel((unsigned long)rxq->bd_dma + sizeof(struct bufdesc_ex)
- * rxq->rx_ring_size, fep->hwp + FEC_X_DES_START(0));
- else
- writel((unsigned long)rxq->bd_dma + sizeof(struct bufdesc)
- * rxq->rx_ring_size, fep->hwp + FEC_X_DES_START(0));
+ fec_enet_enable_ring(ndev);
-
- txq = fep->tx_queue[0];
- for (i = 0; i <= TX_RING_MOD_MASK; i++) {
- if (txq->tx_skbuff[i]) {
- dev_kfree_skb_any(txq->tx_skbuff[i]);
- txq->tx_skbuff[i] = NULL;
- }
- }
+ /* Reset tx SKB buffers. */
+ fec_enet_reset_skb(ndev);
/* Enable MII mode */
if (fep->full_duplex == DUPLEX_FULL) {
@@ -1057,7 +1092,8 @@ fec_restart(struct net_device *ndev)
/* And last, enable the transmit and receive processing */
writel(ecntl, fep->hwp + FEC_ECNTRL);
- writel(0, fep->hwp + FEC_R_DES_ACTIVE(0));
+ for (i = 0; i < fep->num_rx_queues; i++)
+ writel(0, fep->hwp + FEC_R_DES_ACTIVE(i));
if (fep->bufdesc_ex)
fec_ptp_start_cyclecounter(ndev);
@@ -2233,41 +2269,122 @@ static void fec_enet_free_buffers(struct net_device *ndev)
struct bufdesc *bdp;
struct fec_enet_priv_tx_q *txq;
struct fec_enet_priv_rx_q *rxq;
+ unsigned int q;
+
+ for (q = 0; q < fep->num_rx_queues; q++) {
+ rxq = fep->rx_queue[q];
+ bdp = rxq->rx_bd_base;
+ for (i = 0; i < rxq->rx_ring_size; i++) {
+ skb = rxq->rx_skbuff[i];
+ rxq->rx_skbuff[i] = NULL;
+ if (skb) {
+ dma_unmap_single(&fep->pdev->dev,
+ bdp->cbd_bufaddr,
+ FEC_ENET_RX_FRSIZE,
+ DMA_FROM_DEVICE);
+ dev_kfree_skb(skb);
+ }
+ bdp = fec_enet_get_nextdesc(bdp, fep, q);
+ }
+ }
- rxq = fep->rx_queue[0];
- bdp = rxq->rx_bd_base;
- for (i = 0; i < rxq->rx_ring_size; i++) {
- skb = rxq->rx_skbuff[i];
- rxq->rx_skbuff[i] = NULL;
- if (skb) {
- dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr,
- FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE);
+ for (q = 0; q < fep->num_tx_queues; q++) {
+ txq = fep->tx_queue[q];
+ bdp = txq->tx_bd_base;
+ for (i = 0; i < txq->tx_ring_size; i++) {
+ kfree(txq->tx_bounce[i]);
+ txq->tx_bounce[i] = NULL;
+ skb = txq->tx_skbuff[i];
+ txq->tx_skbuff[i] = NULL;
dev_kfree_skb(skb);
}
- bdp = fec_enet_get_nextdesc(bdp, fep, 0);
}
+}
- txq = fep->tx_queue[0];
- bdp = txq->tx_bd_base;
- for (i = 0; i < txq->tx_ring_size; i++) {
- kfree(txq->tx_bounce[i]);
- txq->tx_bounce[i] = NULL;
- skb = txq->tx_skbuff[i];
- txq->tx_skbuff[i] = NULL;
- dev_kfree_skb(skb);
+static void fec_enet_free_queue(struct net_device *ndev)
+{
+ struct fec_enet_private *fep = netdev_priv(ndev);
+ int i;
+ struct fec_enet_priv_tx_q *txq;
+
+ for (i = 0; i < fep->num_tx_queues; i++)
+ if (fep->tx_queue[i] && fep->tx_queue[i]->tso_hdrs) {
+ txq = fep->tx_queue[i];
+ dma_free_coherent(NULL,
+ txq->tx_ring_size * TSO_HEADER_SIZE,
+ txq->tso_hdrs,
+ txq->tso_hdrs_dma);
+ }
+
+ for (i = 0; i < fep->num_rx_queues; i++)
+ if (fep->rx_queue[i])
+ kfree(fep->rx_queue[i]);
+
+ for (i = 0; i < fep->num_tx_queues; i++)
+ if (fep->tx_queue[i])
+ kfree(fep->tx_queue[i]);
+}
+
+static int fec_enet_alloc_queue(struct net_device *ndev)
+{
+ struct fec_enet_private *fep = netdev_priv(ndev);
+ int i;
+ int ret = 0;
+ struct fec_enet_priv_tx_q *txq;
+
+ for (i = 0; i < fep->num_tx_queues; i++) {
+ txq = kzalloc(sizeof(*txq), GFP_KERNEL);
+ if (!txq) {
+ ret = -ENOMEM;
+ goto alloc_failed;
+ }
+
+ fep->tx_queue[i] = txq;
+ txq->tx_ring_size = TX_RING_SIZE;
+ fep->total_tx_ring_size += fep->tx_queue[i]->tx_ring_size;
+
+ txq->tx_stop_threshold = FEC_MAX_SKB_DESCS;
+ txq->tx_wake_threshold =
+ (txq->tx_ring_size - txq->tx_stop_threshold) / 2;
+
+ txq->tso_hdrs = dma_alloc_coherent(NULL,
+ txq->tx_ring_size * TSO_HEADER_SIZE,
+ &txq->tso_hdrs_dma,
+ GFP_KERNEL);
+ if (!txq->tso_hdrs) {
+ ret = -ENOMEM;
+ goto alloc_failed;
+ }
}
+
+ for (i = 0; i < fep->num_rx_queues; i++) {
+ fep->rx_queue[i] = kzalloc(sizeof(*fep->rx_queue[i]),
+ GFP_KERNEL);
+ if (!fep->rx_queue[i]) {
+ ret = -ENOMEM;
+ goto alloc_failed;
+ }
+
+ fep->rx_queue[i]->rx_ring_size = RX_RING_SIZE;
+ fep->total_rx_ring_size += fep->rx_queue[i]->rx_ring_size;
+ }
+ return ret;
+
+alloc_failed:
+ fec_enet_free_queue(ndev);
+ return ret;
}
-static int fec_enet_alloc_buffers(struct net_device *ndev)
+static int
+fec_enet_alloc_rxq_buffers(struct net_device *ndev, unsigned int queue)
{
struct fec_enet_private *fep = netdev_priv(ndev);
unsigned int i;
struct sk_buff *skb;
struct bufdesc *bdp;
- struct fec_enet_priv_tx_q *txq;
struct fec_enet_priv_rx_q *rxq;
- rxq = fep->rx_queue[0];
+ rxq = fep->rx_queue[queue];
bdp = rxq->rx_bd_base;
for (i = 0; i < rxq->rx_ring_size; i++) {
dma_addr_t addr;
@@ -2294,14 +2411,28 @@ static int fec_enet_alloc_buffers(struct net_device *ndev)
ebdp->cbd_esc = BD_ENET_RX_INT;
}
- bdp = fec_enet_get_nextdesc(bdp, fep, 0);
+ bdp = fec_enet_get_nextdesc(bdp, fep, queue);
}
/* Set the last buffer to wrap. */
- bdp = fec_enet_get_prevdesc(bdp, fep, 0);
+ bdp = fec_enet_get_prevdesc(bdp, fep, queue);
bdp->cbd_sc |= BD_SC_WRAP;
+ return 0;
- txq = fep->tx_queue[0];
+ err_alloc:
+ fec_enet_free_buffers(ndev);
+ return -ENOMEM;
+}
+
+static int
+fec_enet_alloc_txq_buffers(struct net_device *ndev, unsigned int queue)
+{
+ struct fec_enet_private *fep = netdev_priv(ndev);
+ unsigned int i;
+ struct bufdesc *bdp;
+ struct fec_enet_priv_tx_q *txq;
+
+ txq = fep->tx_queue[queue];
bdp = txq->tx_bd_base;
for (i = 0; i < txq->tx_ring_size; i++) {
txq->tx_bounce[i] = kmalloc(FEC_ENET_TX_FRSIZE, GFP_KERNEL);
@@ -2316,11 +2447,11 @@ static int fec_enet_alloc_buffers(struct net_device *ndev)
ebdp->cbd_esc = BD_ENET_TX_INT;
}
- bdp = fec_enet_get_nextdesc(bdp, fep, 0);
+ bdp = fec_enet_get_nextdesc(bdp, fep, queue);
}
/* Set the last buffer to wrap. */
- bdp = fec_enet_get_prevdesc(bdp, fep, 0);
+ bdp = fec_enet_get_prevdesc(bdp, fep, queue);
bdp->cbd_sc |= BD_SC_WRAP;
return 0;
@@ -2330,6 +2461,21 @@ static int fec_enet_alloc_buffers(struct net_device *ndev)
return -ENOMEM;
}
+static int fec_enet_alloc_buffers(struct net_device *ndev)
+{
+ struct fec_enet_private *fep = netdev_priv(ndev);
+ unsigned int i;
+
+ for (i = 0; i < fep->num_rx_queues; i++)
+ if (fec_enet_alloc_rxq_buffers(ndev, i))
+ return -ENOMEM;
+
+ for (i = 0; i < fep->num_tx_queues; i++)
+ if (fec_enet_alloc_txq_buffers(ndev, i))
+ return -ENOMEM;
+ return 0;
+}
+
static int
fec_enet_open(struct net_device *ndev)
{
@@ -2579,28 +2725,9 @@ static int fec_enet_init(struct net_device *ndev)
struct bufdesc *cbd_base;
dma_addr_t bd_dma;
int bd_size;
+ unsigned int i;
- txq = kzalloc(sizeof(*txq), GFP_KERNEL);
- if (!txq)
- return -ENOMEM;
- fep->tx_queue[0] = txq;
-
- rxq = kzalloc(sizeof(*rxq), GFP_KERNEL);
- if (!rxq) {
- kfree(txq);
- return -ENOMEM;
- }
-
- fep->rx_queue[0] = rxq;
-
-
- txq->tx_ring_size = TX_RING_SIZE;
- rxq->rx_ring_size = RX_RING_SIZE;
- fep->total_tx_ring_size = txq->tx_ring_size;
- fep->total_rx_ring_size = rxq->rx_ring_size;
-
- txq->tx_stop_threshold = FEC_MAX_SKB_DESCS;
- txq->tx_wake_threshold = (txq->tx_ring_size - txq->tx_stop_threshold) / 2;
+ fec_enet_alloc_queue(ndev);
if (fep->bufdesc_ex)
fep->bufdesc_size = sizeof(struct bufdesc_ex);
@@ -2613,17 +2740,6 @@ static int fec_enet_init(struct net_device *ndev)
cbd_base = dma_alloc_coherent(NULL, bd_size, &bd_dma,
GFP_KERNEL);
if (!cbd_base) {
- kfree(rxq);
- kfree(txq);
- return -ENOMEM;
- }
-
- txq->tso_hdrs = dma_alloc_coherent(NULL, txq->tx_ring_size * TSO_HEADER_SIZE,
- &txq->tso_hdrs_dma, GFP_KERNEL);
- if (!txq->tso_hdrs) {
- kfree(rxq);
- kfree(txq);
- dma_free_coherent(NULL, bd_size, cbd_base, bd_dma);
return -ENOMEM;
}
@@ -2635,12 +2751,35 @@ static int fec_enet_init(struct net_device *ndev)
fec_set_mac_address(ndev, NULL);
/* Set receive and transmit descriptor base. */
- rxq->rx_bd_base = cbd_base;
- if (fep->bufdesc_ex)
- txq->tx_bd_base = (struct bufdesc *)
- (((struct bufdesc_ex *)cbd_base) + rxq->rx_ring_size);
- else
- txq->tx_bd_base = cbd_base + rxq->rx_ring_size;
+ for (i = 0; i < fep->num_rx_queues; i++) {
+ rxq = fep->rx_queue[i];
+ rxq->index = i;
+ rxq->rx_bd_base = (struct bufdesc *)cbd_base;
+ rxq->bd_dma = bd_dma;
+ if (fep->bufdesc_ex) {
+ bd_dma += sizeof(struct bufdesc_ex) * rxq->rx_ring_size;
+ cbd_base = (struct bufdesc *)
+ (((struct bufdesc_ex *)cbd_base) + rxq->rx_ring_size);
+ } else {
+ bd_dma += sizeof(struct bufdesc) * rxq->rx_ring_size;
+ cbd_base += rxq->rx_ring_size;
+ }
+ }
+
+ for (i = 0; i < fep->num_tx_queues; i++) {
+ txq = fep->tx_queue[i];
+ txq->index = i;
+ txq->tx_bd_base = (struct bufdesc *)cbd_base;
+ txq->bd_dma = bd_dma;
+ if (fep->bufdesc_ex) {
+ bd_dma += sizeof(struct bufdesc_ex) * txq->tx_ring_size;
+ cbd_base = (struct bufdesc *)
+ (((struct bufdesc_ex *)cbd_base) + txq->tx_ring_size);
+ } else {
+ bd_dma += sizeof(struct bufdesc) * txq->tx_ring_size;
+ cbd_base += txq->tx_ring_size;
+ }
+ }
/* The FEC Ethernet specific entries in the device structure */
--
1.9.1
^ permalink raw reply related
* [Patch v4 net-next 03/12] net: fec: change data structure to support multiqueue
From: Frank.Li @ 2014-09-12 21:00 UTC (permalink / raw)
To: b38611, davem, netdev, lznuaa
Cc: devicetree, Frank Li, Fugang Duan, linux, shawn.guo,
linux-arm-kernel
In-Reply-To: <1410555657-10744-1-git-send-email-Frank.Li@freescale.com>
From: Fugang Duan <B38611@freescale.com>
This patch just change data structure to support multi-queue.
Only 1 queue enabled.
Ethernet multiqueue mechanism can improve performance in SMP system.
For single hw queue, multiqueue can balance cpu loading.
For multi hw queues, multiple cores can process network packets in parallel,
and refer the article for the detail advantage for multiqueue:
http://vger.kernel.org/~davem/davem_nyc09.pdf
Signed-off-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Frank Li <frank.li@freescale.com>
---
drivers/net/ethernet/freescale/fec.h | 115 +++++--
drivers/net/ethernet/freescale/fec_main.c | 481 +++++++++++++++++++-----------
2 files changed, 400 insertions(+), 196 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index 635772b..b2b91f8 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -27,8 +27,8 @@
*/
#define FEC_IEVENT 0x004 /* Interrupt event reg */
#define FEC_IMASK 0x008 /* Interrupt mask reg */
-#define FEC_R_DES_ACTIVE 0x010 /* Receive descriptor reg */
-#define FEC_X_DES_ACTIVE 0x014 /* Transmit descriptor reg */
+#define FEC_R_DES_ACTIVE_0 0x010 /* Receive descriptor reg */
+#define FEC_X_DES_ACTIVE_0 0x014 /* Transmit descriptor reg */
#define FEC_ECNTRL 0x024 /* Ethernet control reg */
#define FEC_MII_DATA 0x040 /* MII manage frame reg */
#define FEC_MII_SPEED 0x044 /* MII speed control reg */
@@ -45,14 +45,26 @@
#define FEC_X_WMRK 0x144 /* FIFO transmit water mark */
#define FEC_R_BOUND 0x14c /* FIFO receive bound reg */
#define FEC_R_FSTART 0x150 /* FIFO receive start reg */
-#define FEC_R_DES_START 0x180 /* Receive descriptor ring */
-#define FEC_X_DES_START 0x184 /* Transmit descriptor ring */
+#define FEC_R_DES_START_1 0x160 /* Receive descriptor ring 1 */
+#define FEC_X_DES_START_1 0x164 /* Transmit descriptor ring 1 */
+#define FEC_R_DES_START_2 0x16c /* Receive descriptor ring 2 */
+#define FEC_X_DES_START_2 0x170 /* Transmit descriptor ring 2 */
+#define FEC_R_DES_START_0 0x180 /* Receive descriptor ring */
+#define FEC_X_DES_START_0 0x184 /* Transmit descriptor ring */
#define FEC_R_BUFF_SIZE 0x188 /* Maximum receive buff size */
#define FEC_R_FIFO_RSFL 0x190 /* Receive FIFO section full threshold */
#define FEC_R_FIFO_RSEM 0x194 /* Receive FIFO section empty threshold */
#define FEC_R_FIFO_RAEM 0x198 /* Receive FIFO almost empty threshold */
#define FEC_R_FIFO_RAFL 0x19c /* Receive FIFO almost full threshold */
#define FEC_RACC 0x1C4 /* Receive Accelerator function */
+#define FEC_RCMR_1 0x1c8 /* Receive classification match ring 1 */
+#define FEC_RCMR_2 0x1cc /* Receive classification match ring 2 */
+#define FEC_DMA_CFG_1 0x1d8 /* DMA class configuration for ring 1 */
+#define FEC_DMA_CFG_2 0x1dc /* DMA class Configuration for ring 2 */
+#define FEC_R_DES_ACTIVE_1 0x1e0 /* Rx descriptor active for ring 1 */
+#define FEC_X_DES_ACTIVE_1 0x1e4 /* Tx descriptor active for ring 1 */
+#define FEC_R_DES_ACTIVE_2 0x1e8 /* Rx descriptor active for ring 2 */
+#define FEC_X_DES_ACTIVE_2 0x1ec /* Tx descriptor active for ring 2 */
#define FEC_MIIGSK_CFGR 0x300 /* MIIGSK Configuration reg */
#define FEC_MIIGSK_ENR 0x308 /* MIIGSK Enable reg */
@@ -233,6 +245,43 @@ struct bufdesc_ex {
/* This device has up to three irqs on some platforms */
#define FEC_IRQ_NUM 3
+/* Maximum number of queues supported
+ * ENET with AVB IP can support up to 3 independent tx queues and rx queues.
+ * User can point the queue number that is less than or equal to 3.
+ */
+#define FEC_ENET_MAX_TX_QS 3
+#define FEC_ENET_MAX_RX_QS 3
+
+#define FEC_R_DES_START(X) ((X == 1) ? FEC_R_DES_START_1 : \
+ ((X == 2) ? \
+ FEC_R_DES_START_2 : FEC_R_DES_START_0))
+#define FEC_X_DES_START(X) ((X == 1) ? FEC_X_DES_START_1 : \
+ ((X == 2) ? \
+ FEC_X_DES_START_2 : FEC_X_DES_START_0))
+#define FEC_R_DES_ACTIVE(X) ((X == 1) ? FEC_R_DES_ACTIVE_1 : \
+ ((X == 2) ? \
+ FEC_R_DES_ACTIVE_2 : FEC_R_DES_ACTIVE_0))
+#define FEC_X_DES_ACTIVE(X) ((X == 1) ? FEC_X_DES_ACTIVE_1 : \
+ ((X == 2) ? \
+ FEC_X_DES_ACTIVE_2 : FEC_X_DES_ACTIVE_0))
+
+#define FEC_DMA_CFG(X) ((X == 2) ? FEC_DMA_CFG_2 : FEC_DMA_CFG_1)
+
+#define DMA_CLASS_EN (1 << 16)
+#define FEC_RCMR(X) ((X == 2) ? FEC_RCMR_2 : FEC_RCMR_1)
+#define IDLE_SLOPE_MASK 0xFFFF
+#define IDLE_SLOPE_1 0x200 /* BW fraction: 0.5 */
+#define IDLE_SLOPE_2 0x200 /* BW fraction: 0.5 */
+#define IDLE_SLOPE(X) ((X == 1) ? (IDLE_SLOPE_1 & IDLE_SLOPE_MASK) : \
+ (IDLE_SLOPE_2 & IDLE_SLOPE_MASK))
+#define RCMR_MATCHEN (0x1 << 16)
+#define RCMR_CMP_CFG(v, n) ((v & 0x7) << (n << 2))
+#define RCMR_CMP_1 (RCMR_CMP_CFG(0, 0) | RCMR_CMP_CFG(1, 1) | \
+ RCMR_CMP_CFG(2, 2) | RCMR_CMP_CFG(3, 3))
+#define RCMR_CMP_2 (RCMR_CMP_CFG(4, 0) | RCMR_CMP_CFG(5, 1) | \
+ RCMR_CMP_CFG(6, 2) | RCMR_CMP_CFG(7, 3))
+#define RCMR_CMP(X) ((X == 1) ? RCMR_CMP_1 : RCMR_CMP_2)
+
/* The number of Tx and Rx buffers. These are allocated from the page
* pool. The code may assume these are power of two, so it it best
* to keep them that size.
@@ -256,6 +305,35 @@ struct bufdesc_ex {
#define FLAG_RX_CSUM_ENABLED (BD_ENET_RX_ICE | BD_ENET_RX_PCR)
#define FLAG_RX_CSUM_ERROR (BD_ENET_RX_ICE | BD_ENET_RX_PCR)
+struct fec_enet_priv_tx_q {
+ int index;
+ unsigned char *tx_bounce[TX_RING_SIZE];
+ struct sk_buff *tx_skbuff[TX_RING_SIZE];
+
+ dma_addr_t bd_dma;
+ struct bufdesc *tx_bd_base;
+ uint tx_ring_size;
+
+ unsigned short tx_stop_threshold;
+ unsigned short tx_wake_threshold;
+
+ struct bufdesc *cur_tx;
+ struct bufdesc *dirty_tx;
+ char *tso_hdrs;
+ dma_addr_t tso_hdrs_dma;
+};
+
+struct fec_enet_priv_rx_q {
+ int index;
+ struct sk_buff *rx_skbuff[RX_RING_SIZE];
+
+ dma_addr_t bd_dma;
+ struct bufdesc *rx_bd_base;
+ uint rx_ring_size;
+
+ struct bufdesc *cur_rx;
+};
+
/* The FEC buffer descriptors track the ring buffers. The rx_bd_base and
* tx_bd_base always point to the base of the buffer descriptors. The
* cur_rx and cur_tx point to the currently available buffer.
@@ -280,29 +358,18 @@ struct fec_enet_private {
struct mutex ptp_clk_mutex;
/* The saved address of a sent-in-place packet/buffer, for skfree(). */
- unsigned char *tx_bounce[TX_RING_SIZE];
- struct sk_buff *tx_skbuff[TX_RING_SIZE];
- struct sk_buff *rx_skbuff[RX_RING_SIZE];
+ struct fec_enet_priv_tx_q *tx_queue[FEC_ENET_MAX_TX_QS];
+ struct fec_enet_priv_rx_q *rx_queue[FEC_ENET_MAX_RX_QS];
- /* CPM dual port RAM relative addresses */
- dma_addr_t bd_dma;
- /* Address of Rx and Tx buffers */
- struct bufdesc *rx_bd_base;
- struct bufdesc *tx_bd_base;
- /* The next free ring entry */
- struct bufdesc *cur_rx, *cur_tx;
- /* The ring entries to be free()ed */
- struct bufdesc *dirty_tx;
+ unsigned int total_tx_ring_size;
+ unsigned int total_rx_ring_size;
- unsigned short bufdesc_size;
- unsigned short tx_ring_size;
- unsigned short rx_ring_size;
- unsigned short tx_stop_threshold;
- unsigned short tx_wake_threshold;
+ unsigned long work_tx;
+ unsigned long work_rx;
+ unsigned long work_ts;
+ unsigned long work_mdio;
- /* Software TSO */
- char *tso_hdrs;
- dma_addr_t tso_hdrs_dma;
+ unsigned short bufdesc_size;
struct platform_device *pdev;
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index ee9f04f..4c0d2ee 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -72,6 +72,8 @@ static void set_multicast_list(struct net_device *ndev);
#define DRIVER_NAME "fec"
+#define FEC_ENET_GET_QUQUE(_x) ((_x == 0) ? 1 : ((_x == 1) ? 2 : 0))
+
/* Pause frame feild and FIFO threshold */
#define FEC_ENET_FCE (1 << 5)
#define FEC_ENET_RSEM_V 0x84
@@ -258,22 +260,26 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
static int mii_cnt;
static inline
-struct bufdesc *fec_enet_get_nextdesc(struct bufdesc *bdp, struct fec_enet_private *fep)
+struct bufdesc *fec_enet_get_nextdesc(struct bufdesc *bdp,
+ struct fec_enet_private *fep,
+ int queue_id)
{
struct bufdesc *new_bd = bdp + 1;
struct bufdesc_ex *ex_new_bd = (struct bufdesc_ex *)bdp + 1;
+ struct fec_enet_priv_tx_q *txq = fep->tx_queue[queue_id];
+ struct fec_enet_priv_rx_q *rxq = fep->rx_queue[queue_id];
struct bufdesc_ex *ex_base;
struct bufdesc *base;
int ring_size;
- if (bdp >= fep->tx_bd_base) {
- base = fep->tx_bd_base;
- ring_size = fep->tx_ring_size;
- ex_base = (struct bufdesc_ex *)fep->tx_bd_base;
+ if (bdp >= txq->tx_bd_base) {
+ base = txq->tx_bd_base;
+ ring_size = txq->tx_ring_size;
+ ex_base = (struct bufdesc_ex *)txq->tx_bd_base;
} else {
- base = fep->rx_bd_base;
- ring_size = fep->rx_ring_size;
- ex_base = (struct bufdesc_ex *)fep->rx_bd_base;
+ base = rxq->rx_bd_base;
+ ring_size = rxq->rx_ring_size;
+ ex_base = (struct bufdesc_ex *)rxq->rx_bd_base;
}
if (fep->bufdesc_ex)
@@ -285,22 +291,26 @@ struct bufdesc *fec_enet_get_nextdesc(struct bufdesc *bdp, struct fec_enet_priva
}
static inline
-struct bufdesc *fec_enet_get_prevdesc(struct bufdesc *bdp, struct fec_enet_private *fep)
+struct bufdesc *fec_enet_get_prevdesc(struct bufdesc *bdp,
+ struct fec_enet_private *fep,
+ int queue_id)
{
struct bufdesc *new_bd = bdp - 1;
struct bufdesc_ex *ex_new_bd = (struct bufdesc_ex *)bdp - 1;
+ struct fec_enet_priv_tx_q *txq = fep->tx_queue[queue_id];
+ struct fec_enet_priv_rx_q *rxq = fep->rx_queue[queue_id];
struct bufdesc_ex *ex_base;
struct bufdesc *base;
int ring_size;
- if (bdp >= fep->tx_bd_base) {
- base = fep->tx_bd_base;
- ring_size = fep->tx_ring_size;
- ex_base = (struct bufdesc_ex *)fep->tx_bd_base;
+ if (bdp >= txq->tx_bd_base) {
+ base = txq->tx_bd_base;
+ ring_size = txq->tx_ring_size;
+ ex_base = (struct bufdesc_ex *)txq->tx_bd_base;
} else {
- base = fep->rx_bd_base;
- ring_size = fep->rx_ring_size;
- ex_base = (struct bufdesc_ex *)fep->rx_bd_base;
+ base = rxq->rx_bd_base;
+ ring_size = rxq->rx_ring_size;
+ ex_base = (struct bufdesc_ex *)rxq->rx_bd_base;
}
if (fep->bufdesc_ex)
@@ -316,14 +326,15 @@ static int fec_enet_get_bd_index(struct bufdesc *base, struct bufdesc *bdp,
return ((const char *)bdp - (const char *)base) / fep->bufdesc_size;
}
-static int fec_enet_get_free_txdesc_num(struct fec_enet_private *fep)
+static int fec_enet_get_free_txdesc_num(struct fec_enet_private *fep,
+ struct fec_enet_priv_tx_q *txq)
{
int entries;
- entries = ((const char *)fep->dirty_tx -
- (const char *)fep->cur_tx) / fep->bufdesc_size - 1;
+ entries = ((const char *)txq->dirty_tx -
+ (const char *)txq->cur_tx) / fep->bufdesc_size - 1;
- return entries > 0 ? entries : entries + fep->tx_ring_size;
+ return entries > 0 ? entries : entries + txq->tx_ring_size;
}
static void *swap_buffer(void *bufaddr, int len)
@@ -340,22 +351,26 @@ static void *swap_buffer(void *bufaddr, int len)
static void fec_dump(struct net_device *ndev)
{
struct fec_enet_private *fep = netdev_priv(ndev);
- struct bufdesc *bdp = fep->tx_bd_base;
- unsigned int index = 0;
+ struct bufdesc *bdp;
+ struct fec_enet_priv_tx_q *txq;
+ int index = 0;
netdev_info(ndev, "TX ring dump\n");
pr_info("Nr SC addr len SKB\n");
+ txq = fep->tx_queue[0];
+ bdp = txq->tx_bd_base;
+
do {
pr_info("%3u %c%c 0x%04x 0x%08lx %4u %p\n",
index,
- bdp == fep->cur_tx ? 'S' : ' ',
- bdp == fep->dirty_tx ? 'H' : ' ',
+ bdp == txq->cur_tx ? 'S' : ' ',
+ bdp == txq->dirty_tx ? 'H' : ' ',
bdp->cbd_sc, bdp->cbd_bufaddr, bdp->cbd_datlen,
- fep->tx_skbuff[index]);
- bdp = fec_enet_get_nextdesc(bdp, fep);
+ txq->tx_skbuff[index]);
+ bdp = fec_enet_get_nextdesc(bdp, fep, 0);
index++;
- } while (bdp != fep->tx_bd_base);
+ } while (bdp != txq->tx_bd_base);
}
static inline bool is_ipv4_pkt(struct sk_buff *skb)
@@ -381,14 +396,17 @@ fec_enet_clear_csum(struct sk_buff *skb, struct net_device *ndev)
}
static int
-fec_enet_txq_submit_frag_skb(struct sk_buff *skb, struct net_device *ndev)
+fec_enet_txq_submit_frag_skb(struct fec_enet_priv_tx_q *txq,
+ struct sk_buff *skb,
+ struct net_device *ndev)
{
struct fec_enet_private *fep = netdev_priv(ndev);
const struct platform_device_id *id_entry =
platform_get_device_id(fep->pdev);
- struct bufdesc *bdp = fep->cur_tx;
+ struct bufdesc *bdp = txq->cur_tx;
struct bufdesc_ex *ebdp;
int nr_frags = skb_shinfo(skb)->nr_frags;
+ unsigned short queue = skb_get_queue_mapping(skb);
int frag, frag_len;
unsigned short status;
unsigned int estatus = 0;
@@ -400,7 +418,7 @@ fec_enet_txq_submit_frag_skb(struct sk_buff *skb, struct net_device *ndev)
for (frag = 0; frag < nr_frags; frag++) {
this_frag = &skb_shinfo(skb)->frags[frag];
- bdp = fec_enet_get_nextdesc(bdp, fep);
+ bdp = fec_enet_get_nextdesc(bdp, fep, queue);
ebdp = (struct bufdesc_ex *)bdp;
status = bdp->cbd_sc;
@@ -428,11 +446,11 @@ fec_enet_txq_submit_frag_skb(struct sk_buff *skb, struct net_device *ndev)
bufaddr = page_address(this_frag->page.p) + this_frag->page_offset;
- index = fec_enet_get_bd_index(fep->tx_bd_base, bdp, fep);
+ index = fec_enet_get_bd_index(txq->tx_bd_base, bdp, fep);
if (((unsigned long) bufaddr) & FEC_ALIGNMENT ||
id_entry->driver_data & FEC_QUIRK_SWAP_FRAME) {
- memcpy(fep->tx_bounce[index], bufaddr, frag_len);
- bufaddr = fep->tx_bounce[index];
+ memcpy(txq->tx_bounce[index], bufaddr, frag_len);
+ bufaddr = txq->tx_bounce[index];
if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
swap_buffer(bufaddr, frag_len);
@@ -452,21 +470,22 @@ fec_enet_txq_submit_frag_skb(struct sk_buff *skb, struct net_device *ndev)
bdp->cbd_sc = status;
}
- fep->cur_tx = bdp;
+ txq->cur_tx = bdp;
return 0;
dma_mapping_error:
- bdp = fep->cur_tx;
+ bdp = txq->cur_tx;
for (i = 0; i < frag; i++) {
- bdp = fec_enet_get_nextdesc(bdp, fep);
+ bdp = fec_enet_get_nextdesc(bdp, fep, queue);
dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr,
bdp->cbd_datlen, DMA_TO_DEVICE);
}
return NETDEV_TX_OK;
}
-static int fec_enet_txq_submit_skb(struct sk_buff *skb, struct net_device *ndev)
+static int fec_enet_txq_submit_skb(struct fec_enet_priv_tx_q *txq,
+ struct sk_buff *skb, struct net_device *ndev)
{
struct fec_enet_private *fep = netdev_priv(ndev);
const struct platform_device_id *id_entry =
@@ -477,12 +496,13 @@ static int fec_enet_txq_submit_skb(struct sk_buff *skb, struct net_device *ndev)
dma_addr_t addr;
unsigned short status;
unsigned short buflen;
+ unsigned short queue;
unsigned int estatus = 0;
unsigned int index;
int entries_free;
int ret;
- entries_free = fec_enet_get_free_txdesc_num(fep);
+ entries_free = fec_enet_get_free_txdesc_num(fep, txq);
if (entries_free < MAX_SKB_FRAGS + 1) {
dev_kfree_skb_any(skb);
if (net_ratelimit())
@@ -497,7 +517,7 @@ static int fec_enet_txq_submit_skb(struct sk_buff *skb, struct net_device *ndev)
}
/* Fill in a Tx ring entry */
- bdp = fep->cur_tx;
+ bdp = txq->cur_tx;
status = bdp->cbd_sc;
status &= ~BD_ENET_TX_STATS;
@@ -505,11 +525,12 @@ static int fec_enet_txq_submit_skb(struct sk_buff *skb, struct net_device *ndev)
bufaddr = skb->data;
buflen = skb_headlen(skb);
- index = fec_enet_get_bd_index(fep->tx_bd_base, bdp, fep);
+ queue = skb_get_queue_mapping(skb);
+ index = fec_enet_get_bd_index(txq->tx_bd_base, bdp, fep);
if (((unsigned long) bufaddr) & FEC_ALIGNMENT ||
id_entry->driver_data & FEC_QUIRK_SWAP_FRAME) {
- memcpy(fep->tx_bounce[index], skb->data, buflen);
- bufaddr = fep->tx_bounce[index];
+ memcpy(txq->tx_bounce[index], skb->data, buflen);
+ bufaddr = txq->tx_bounce[index];
if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
swap_buffer(bufaddr, buflen);
@@ -525,7 +546,7 @@ static int fec_enet_txq_submit_skb(struct sk_buff *skb, struct net_device *ndev)
}
if (nr_frags) {
- ret = fec_enet_txq_submit_frag_skb(skb, ndev);
+ ret = fec_enet_txq_submit_frag_skb(txq, skb, ndev);
if (ret)
return ret;
} else {
@@ -553,10 +574,10 @@ static int fec_enet_txq_submit_skb(struct sk_buff *skb, struct net_device *ndev)
ebdp->cbd_esc = estatus;
}
- last_bdp = fep->cur_tx;
- index = fec_enet_get_bd_index(fep->tx_bd_base, last_bdp, fep);
+ last_bdp = txq->cur_tx;
+ index = fec_enet_get_bd_index(txq->tx_bd_base, last_bdp, fep);
/* Save skb pointer */
- fep->tx_skbuff[index] = skb;
+ txq->tx_skbuff[index] = skb;
bdp->cbd_datlen = buflen;
bdp->cbd_bufaddr = addr;
@@ -568,22 +589,23 @@ static int fec_enet_txq_submit_skb(struct sk_buff *skb, struct net_device *ndev)
bdp->cbd_sc = status;
/* If this was the last BD in the ring, start at the beginning again. */
- bdp = fec_enet_get_nextdesc(last_bdp, fep);
+ bdp = fec_enet_get_nextdesc(last_bdp, fep, queue);
skb_tx_timestamp(skb);
- fep->cur_tx = bdp;
+ txq->cur_tx = bdp;
/* Trigger transmission start */
- writel(0, fep->hwp + FEC_X_DES_ACTIVE);
+ writel(0, fep->hwp + FEC_X_DES_ACTIVE(queue));
return 0;
}
static int
-fec_enet_txq_put_data_tso(struct sk_buff *skb, struct net_device *ndev,
- struct bufdesc *bdp, int index, char *data,
- int size, bool last_tcp, bool is_last)
+fec_enet_txq_put_data_tso(struct fec_enet_priv_tx_q *txq, struct sk_buff *skb,
+ struct net_device *ndev,
+ struct bufdesc *bdp, int index, char *data,
+ int size, bool last_tcp, bool is_last)
{
struct fec_enet_private *fep = netdev_priv(ndev);
const struct platform_device_id *id_entry =
@@ -600,8 +622,8 @@ fec_enet_txq_put_data_tso(struct sk_buff *skb, struct net_device *ndev,
if (((unsigned long) data) & FEC_ALIGNMENT ||
id_entry->driver_data & FEC_QUIRK_SWAP_FRAME) {
- memcpy(fep->tx_bounce[index], data, size);
- data = fep->tx_bounce[index];
+ memcpy(txq->tx_bounce[index], data, size);
+ data = txq->tx_bounce[index];
if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
swap_buffer(data, size);
@@ -640,8 +662,9 @@ fec_enet_txq_put_data_tso(struct sk_buff *skb, struct net_device *ndev,
}
static int
-fec_enet_txq_put_hdr_tso(struct sk_buff *skb, struct net_device *ndev,
- struct bufdesc *bdp, int index)
+fec_enet_txq_put_hdr_tso(struct fec_enet_priv_tx_q *txq,
+ struct sk_buff *skb, struct net_device *ndev,
+ struct bufdesc *bdp, int index)
{
struct fec_enet_private *fep = netdev_priv(ndev);
const struct platform_device_id *id_entry =
@@ -657,12 +680,12 @@ fec_enet_txq_put_hdr_tso(struct sk_buff *skb, struct net_device *ndev,
status &= ~BD_ENET_TX_STATS;
status |= (BD_ENET_TX_TC | BD_ENET_TX_READY);
- bufaddr = fep->tso_hdrs + index * TSO_HEADER_SIZE;
- dmabuf = fep->tso_hdrs_dma + index * TSO_HEADER_SIZE;
+ bufaddr = txq->tso_hdrs + index * TSO_HEADER_SIZE;
+ dmabuf = txq->tso_hdrs_dma + index * TSO_HEADER_SIZE;
if (((unsigned long) bufaddr) & FEC_ALIGNMENT ||
id_entry->driver_data & FEC_QUIRK_SWAP_FRAME) {
- memcpy(fep->tx_bounce[index], skb->data, hdr_len);
- bufaddr = fep->tx_bounce[index];
+ memcpy(txq->tx_bounce[index], skb->data, hdr_len);
+ bufaddr = txq->tx_bounce[index];
if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
swap_buffer(bufaddr, hdr_len);
@@ -692,17 +715,20 @@ fec_enet_txq_put_hdr_tso(struct sk_buff *skb, struct net_device *ndev,
return 0;
}
-static int fec_enet_txq_submit_tso(struct sk_buff *skb, struct net_device *ndev)
+static int fec_enet_txq_submit_tso(struct fec_enet_priv_tx_q *txq,
+ struct sk_buff *skb,
+ struct net_device *ndev)
{
struct fec_enet_private *fep = netdev_priv(ndev);
int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
int total_len, data_left;
- struct bufdesc *bdp = fep->cur_tx;
+ struct bufdesc *bdp = txq->cur_tx;
+ unsigned short queue = skb_get_queue_mapping(skb);
struct tso_t tso;
unsigned int index = 0;
int ret;
- if (tso_count_descs(skb) >= fec_enet_get_free_txdesc_num(fep)) {
+ if (tso_count_descs(skb) >= fec_enet_get_free_txdesc_num(fep, txq)) {
dev_kfree_skb_any(skb);
if (net_ratelimit())
netdev_err(ndev, "NOT enough BD for TSO!\n");
@@ -722,14 +748,14 @@ static int fec_enet_txq_submit_tso(struct sk_buff *skb, struct net_device *ndev)
while (total_len > 0) {
char *hdr;
- index = fec_enet_get_bd_index(fep->tx_bd_base, bdp, fep);
+ index = fec_enet_get_bd_index(txq->tx_bd_base, bdp, fep);
data_left = min_t(int, skb_shinfo(skb)->gso_size, total_len);
total_len -= data_left;
/* prepare packet headers: MAC + IP + TCP */
- hdr = fep->tso_hdrs + index * TSO_HEADER_SIZE;
+ hdr = txq->tso_hdrs + index * TSO_HEADER_SIZE;
tso_build_hdr(skb, hdr, &tso, data_left, total_len == 0);
- ret = fec_enet_txq_put_hdr_tso(skb, ndev, bdp, index);
+ ret = fec_enet_txq_put_hdr_tso(txq, skb, ndev, bdp, index);
if (ret)
goto err_release;
@@ -737,10 +763,13 @@ static int fec_enet_txq_submit_tso(struct sk_buff *skb, struct net_device *ndev)
int size;
size = min_t(int, tso.size, data_left);
- bdp = fec_enet_get_nextdesc(bdp, fep);
- index = fec_enet_get_bd_index(fep->tx_bd_base, bdp, fep);
- ret = fec_enet_txq_put_data_tso(skb, ndev, bdp, index, tso.data,
- size, size == data_left,
+ bdp = fec_enet_get_nextdesc(bdp, fep, queue);
+ index = fec_enet_get_bd_index(txq->tx_bd_base,
+ bdp, fep);
+ ret = fec_enet_txq_put_data_tso(txq, skb, ndev,
+ bdp, index,
+ tso.data, size,
+ size == data_left,
total_len == 0);
if (ret)
goto err_release;
@@ -749,17 +778,17 @@ static int fec_enet_txq_submit_tso(struct sk_buff *skb, struct net_device *ndev)
tso_build_data(skb, &tso, size);
}
- bdp = fec_enet_get_nextdesc(bdp, fep);
+ bdp = fec_enet_get_nextdesc(bdp, fep, queue);
}
/* Save skb pointer */
- fep->tx_skbuff[index] = skb;
+ txq->tx_skbuff[index] = skb;
skb_tx_timestamp(skb);
- fep->cur_tx = bdp;
+ txq->cur_tx = bdp;
/* Trigger transmission start */
- writel(0, fep->hwp + FEC_X_DES_ACTIVE);
+ writel(0, fep->hwp + FEC_X_DES_ACTIVE(queue));
return 0;
@@ -773,18 +802,25 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
{
struct fec_enet_private *fep = netdev_priv(ndev);
int entries_free;
+ unsigned short queue;
+ struct fec_enet_priv_tx_q *txq;
+ struct netdev_queue *nq;
int ret;
+ queue = skb_get_queue_mapping(skb);
+ txq = fep->tx_queue[queue];
+ nq = netdev_get_tx_queue(ndev, queue);
+
if (skb_is_gso(skb))
- ret = fec_enet_txq_submit_tso(skb, ndev);
+ ret = fec_enet_txq_submit_tso(txq, skb, ndev);
else
- ret = fec_enet_txq_submit_skb(skb, ndev);
+ ret = fec_enet_txq_submit_skb(txq, skb, ndev);
if (ret)
return ret;
- entries_free = fec_enet_get_free_txdesc_num(fep);
- if (entries_free <= fep->tx_stop_threshold)
- netif_stop_queue(ndev);
+ entries_free = fec_enet_get_free_txdesc_num(fep, txq);
+ if (entries_free <= txq->tx_stop_threshold)
+ netif_tx_stop_queue(nq);
return NETDEV_TX_OK;
}
@@ -794,46 +830,51 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
static void fec_enet_bd_init(struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
+ struct fec_enet_priv_tx_q *txq;
+ struct fec_enet_priv_rx_q *rxq;
struct bufdesc *bdp;
unsigned int i;
/* Initialize the receive buffer descriptors. */
- bdp = fep->rx_bd_base;
- for (i = 0; i < fep->rx_ring_size; i++) {
+ rxq = fep->rx_queue[0];
+ bdp = rxq->rx_bd_base;
+
+ for (i = 0; i < rxq->rx_ring_size; i++) {
/* Initialize the BD for every fragment in the page. */
if (bdp->cbd_bufaddr)
bdp->cbd_sc = BD_ENET_RX_EMPTY;
else
bdp->cbd_sc = 0;
- bdp = fec_enet_get_nextdesc(bdp, fep);
+ bdp = fec_enet_get_nextdesc(bdp, fep, 0);
}
/* Set the last buffer to wrap */
- bdp = fec_enet_get_prevdesc(bdp, fep);
+ bdp = fec_enet_get_prevdesc(bdp, fep, 0);
bdp->cbd_sc |= BD_SC_WRAP;
- fep->cur_rx = fep->rx_bd_base;
+ rxq->cur_rx = rxq->rx_bd_base;
/* ...and the same for transmit */
- bdp = fep->tx_bd_base;
- fep->cur_tx = bdp;
- for (i = 0; i < fep->tx_ring_size; i++) {
+ txq = fep->tx_queue[0];
+ bdp = txq->tx_bd_base;
+ txq->cur_tx = bdp;
+ for (i = 0; i < txq->tx_ring_size; i++) {
/* Initialize the BD for every fragment in the page. */
bdp->cbd_sc = 0;
- if (fep->tx_skbuff[i]) {
- dev_kfree_skb_any(fep->tx_skbuff[i]);
- fep->tx_skbuff[i] = NULL;
+ if (txq->tx_skbuff[i]) {
+ dev_kfree_skb_any(txq->tx_skbuff[i]);
+ txq->tx_skbuff[i] = NULL;
}
bdp->cbd_bufaddr = 0;
- bdp = fec_enet_get_nextdesc(bdp, fep);
+ bdp = fec_enet_get_nextdesc(bdp, fep, 0);
}
/* Set the last buffer to wrap */
- bdp = fec_enet_get_prevdesc(bdp, fep);
+ bdp = fec_enet_get_prevdesc(bdp, fep, 0);
bdp->cbd_sc |= BD_SC_WRAP;
- fep->dirty_tx = bdp;
+ txq->dirty_tx = bdp;
}
/*
@@ -852,6 +893,8 @@ fec_restart(struct net_device *ndev)
u32 temp_mac[2];
u32 rcntl = OPT_FRAME_SIZE | 0x04;
u32 ecntl = 0x2; /* ETHEREN */
+ struct fec_enet_priv_tx_q *txq;
+ struct fec_enet_priv_rx_q *rxq;
/* Whack a reset. We should wait for this. */
writel(1, fep->hwp + FEC_ECNTRL);
@@ -876,19 +919,21 @@ fec_restart(struct net_device *ndev)
fec_enet_bd_init(ndev);
/* Set receive and transmit descriptor base. */
- writel(fep->bd_dma, fep->hwp + FEC_R_DES_START);
+ rxq = fep->rx_queue[0];
+ writel(rxq->bd_dma, fep->hwp + FEC_R_DES_START(0));
if (fep->bufdesc_ex)
- writel((unsigned long)fep->bd_dma + sizeof(struct bufdesc_ex)
- * fep->rx_ring_size, fep->hwp + FEC_X_DES_START);
+ writel((unsigned long)rxq->bd_dma + sizeof(struct bufdesc_ex)
+ * rxq->rx_ring_size, fep->hwp + FEC_X_DES_START(0));
else
- writel((unsigned long)fep->bd_dma + sizeof(struct bufdesc)
- * fep->rx_ring_size, fep->hwp + FEC_X_DES_START);
+ writel((unsigned long)rxq->bd_dma + sizeof(struct bufdesc)
+ * rxq->rx_ring_size, fep->hwp + FEC_X_DES_START(0));
+ txq = fep->tx_queue[0];
for (i = 0; i <= TX_RING_MOD_MASK; i++) {
- if (fep->tx_skbuff[i]) {
- dev_kfree_skb_any(fep->tx_skbuff[i]);
- fep->tx_skbuff[i] = NULL;
+ if (txq->tx_skbuff[i]) {
+ dev_kfree_skb_any(txq->tx_skbuff[i]);
+ txq->tx_skbuff[i] = NULL;
}
}
@@ -1012,7 +1057,7 @@ fec_restart(struct net_device *ndev)
/* And last, enable the transmit and receive processing */
writel(ecntl, fep->hwp + FEC_ECNTRL);
- writel(0, fep->hwp + FEC_R_DES_ACTIVE);
+ writel(0, fep->hwp + FEC_R_DES_ACTIVE(0));
if (fep->bufdesc_ex)
fec_ptp_start_cyclecounter(ndev);
@@ -1097,37 +1142,45 @@ fec_enet_hwtstamp(struct fec_enet_private *fep, unsigned ts,
}
static void
-fec_enet_tx(struct net_device *ndev)
+fec_enet_tx_queue(struct net_device *ndev, u16 queue_id)
{
struct fec_enet_private *fep;
struct bufdesc *bdp;
unsigned short status;
struct sk_buff *skb;
+ struct fec_enet_priv_tx_q *txq;
+ struct netdev_queue *nq;
int index = 0;
int entries_free;
fep = netdev_priv(ndev);
- bdp = fep->dirty_tx;
+
+ queue_id = FEC_ENET_GET_QUQUE(queue_id);
+
+ txq = fep->tx_queue[queue_id];
+ /* get next bdp of dirty_tx */
+ nq = netdev_get_tx_queue(ndev, queue_id);
+ bdp = txq->dirty_tx;
/* get next bdp of dirty_tx */
- bdp = fec_enet_get_nextdesc(bdp, fep);
+ bdp = fec_enet_get_nextdesc(bdp, fep, queue_id);
while (((status = bdp->cbd_sc) & BD_ENET_TX_READY) == 0) {
/* current queue is empty */
- if (bdp == fep->cur_tx)
+ if (bdp == txq->cur_tx)
break;
- index = fec_enet_get_bd_index(fep->tx_bd_base, bdp, fep);
+ index = fec_enet_get_bd_index(txq->tx_bd_base, bdp, fep);
- skb = fep->tx_skbuff[index];
- fep->tx_skbuff[index] = NULL;
- if (!IS_TSO_HEADER(fep, bdp->cbd_bufaddr))
+ skb = txq->tx_skbuff[index];
+ txq->tx_skbuff[index] = NULL;
+ if (!IS_TSO_HEADER(txq, bdp->cbd_bufaddr))
dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr,
bdp->cbd_datlen, DMA_TO_DEVICE);
bdp->cbd_bufaddr = 0;
if (!skb) {
- bdp = fec_enet_get_nextdesc(bdp, fep);
+ bdp = fec_enet_get_nextdesc(bdp, fep, queue_id);
continue;
}
@@ -1169,23 +1222,37 @@ fec_enet_tx(struct net_device *ndev)
/* Free the sk buffer associated with this last transmit */
dev_kfree_skb_any(skb);
- fep->dirty_tx = bdp;
+ txq->dirty_tx = bdp;
/* Update pointer to next buffer descriptor to be transmitted */
- bdp = fec_enet_get_nextdesc(bdp, fep);
+ bdp = fec_enet_get_nextdesc(bdp, fep, queue_id);
/* Since we have freed up a buffer, the ring is no longer full
*/
if (netif_queue_stopped(ndev)) {
- entries_free = fec_enet_get_free_txdesc_num(fep);
- if (entries_free >= fep->tx_wake_threshold)
- netif_wake_queue(ndev);
+ entries_free = fec_enet_get_free_txdesc_num(fep, txq);
+ if (entries_free >= txq->tx_wake_threshold)
+ netif_tx_wake_queue(nq);
}
}
/* ERR006538: Keep the transmitter going */
- if (bdp != fep->cur_tx && readl(fep->hwp + FEC_X_DES_ACTIVE) == 0)
- writel(0, fep->hwp + FEC_X_DES_ACTIVE);
+ if (bdp != txq->cur_tx &&
+ readl(fep->hwp + FEC_X_DES_ACTIVE(queue_id)) == 0)
+ writel(0, fep->hwp + FEC_X_DES_ACTIVE(queue_id));
+}
+
+static void
+fec_enet_tx(struct net_device *ndev)
+{
+ struct fec_enet_private *fep = netdev_priv(ndev);
+ u16 queue_id;
+ /* First process class A queue, then Class B and Best Effort queue */
+ for_each_set_bit(queue_id, &fep->work_tx, FEC_ENET_MAX_TX_QS) {
+ clear_bit(queue_id, &fep->work_tx);
+ fec_enet_tx_queue(ndev, queue_id);
+ }
+ return;
}
/* During a receive, the cur_rx points to the current incoming buffer.
@@ -1194,11 +1261,12 @@ fec_enet_tx(struct net_device *ndev)
* effectively tossing the packet.
*/
static int
-fec_enet_rx(struct net_device *ndev, int budget)
+fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
{
struct fec_enet_private *fep = netdev_priv(ndev);
const struct platform_device_id *id_entry =
platform_get_device_id(fep->pdev);
+ struct fec_enet_priv_rx_q *rxq;
struct bufdesc *bdp;
unsigned short status;
struct sk_buff *skb;
@@ -1213,11 +1281,13 @@ fec_enet_rx(struct net_device *ndev, int budget)
#ifdef CONFIG_M532x
flush_cache_all();
#endif
+ queue_id = FEC_ENET_GET_QUQUE(queue_id);
+ rxq = fep->rx_queue[queue_id];
/* First, grab all of the stats for the incoming packet.
* These get messed up if we get called due to a busy condition.
*/
- bdp = fep->cur_rx;
+ bdp = rxq->cur_rx;
while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) {
@@ -1231,7 +1301,6 @@ fec_enet_rx(struct net_device *ndev, int budget)
if ((status & BD_ENET_RX_LAST) == 0)
netdev_err(ndev, "rcv is not +last\n");
- writel(FEC_ENET_RXF, fep->hwp + FEC_IEVENT);
/* Check for errors. */
if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO |
@@ -1264,8 +1333,8 @@ fec_enet_rx(struct net_device *ndev, int budget)
pkt_len = bdp->cbd_datlen;
ndev->stats.rx_bytes += pkt_len;
- index = fec_enet_get_bd_index(fep->rx_bd_base, bdp, fep);
- data = fep->rx_skbuff[index]->data;
+ index = fec_enet_get_bd_index(rxq->rx_bd_base, bdp, fep);
+ data = rxq->rx_skbuff[index]->data;
dma_sync_single_for_cpu(&fep->pdev->dev, bdp->cbd_bufaddr,
FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE);
@@ -1280,7 +1349,7 @@ fec_enet_rx(struct net_device *ndev, int budget)
/* If this is a VLAN packet remove the VLAN Tag */
vlan_packet_rcvd = false;
if ((ndev->features & NETIF_F_HW_VLAN_CTAG_RX) &&
- fep->bufdesc_ex && (ebdp->cbd_esc & BD_ENET_RX_VLAN)) {
+ fep->bufdesc_ex && (ebdp->cbd_esc & BD_ENET_RX_VLAN)) {
/* Push and remove the vlan tag */
struct vlan_hdr *vlan_header =
(struct vlan_hdr *) (data + ETH_HLEN);
@@ -1308,7 +1377,7 @@ fec_enet_rx(struct net_device *ndev, int budget)
skb_copy_to_linear_data(skb, data, (2 * ETH_ALEN));
if (vlan_packet_rcvd)
payload_offset = (2 * ETH_ALEN) + VLAN_HLEN;
- skb_copy_to_linear_data_offset(skb, (2 * ETH_ALEN),
+ skb_copy_to_linear_data_offset(skb, (2 * ETH_ALEN),
data + payload_offset,
pkt_len - 4 - (2 * ETH_ALEN));
@@ -1357,19 +1426,48 @@ rx_processing_done:
}
/* Update BD pointer to next entry */
- bdp = fec_enet_get_nextdesc(bdp, fep);
+ bdp = fec_enet_get_nextdesc(bdp, fep, queue_id);
/* Doing this here will keep the FEC running while we process
* incoming frames. On a heavily loaded network, we should be
* able to keep up at the expense of system resources.
*/
- writel(0, fep->hwp + FEC_R_DES_ACTIVE);
+ writel(0, fep->hwp + FEC_R_DES_ACTIVE(queue_id));
}
- fep->cur_rx = bdp;
+ rxq->cur_rx = bdp;
+ return pkt_received;
+}
+static int
+fec_enet_rx(struct net_device *ndev, int budget)
+{
+ int pkt_received = 0;
+ u16 queue_id;
+ struct fec_enet_private *fep = netdev_priv(ndev);
+
+ for_each_set_bit(queue_id, &fep->work_rx, FEC_ENET_MAX_RX_QS) {
+ clear_bit(queue_id, &fep->work_rx);
+ pkt_received += fec_enet_rx_queue(ndev,
+ budget - pkt_received, queue_id);
+ }
return pkt_received;
}
+static bool
+fec_enet_collect_events(struct fec_enet_private *fep, uint int_events)
+{
+ if (int_events == 0)
+ return false;
+
+ if (int_events & FEC_ENET_RXF)
+ fep->work_rx |= (1 << 2);
+
+ if (int_events & FEC_ENET_TXF)
+ fep->work_tx |= (1 << 2);
+
+ return true;
+}
+
static irqreturn_t
fec_enet_interrupt(int irq, void *dev_id)
{
@@ -1381,6 +1479,7 @@ fec_enet_interrupt(int irq, void *dev_id)
int_events = readl(fep->hwp + FEC_IEVENT);
writel(int_events & ~napi_mask, fep->hwp + FEC_IEVENT);
+ fec_enet_collect_events(fep, int_events);
if (int_events & napi_mask) {
ret = IRQ_HANDLED;
@@ -2132,25 +2231,29 @@ static void fec_enet_free_buffers(struct net_device *ndev)
unsigned int i;
struct sk_buff *skb;
struct bufdesc *bdp;
-
- bdp = fep->rx_bd_base;
- for (i = 0; i < fep->rx_ring_size; i++) {
- skb = fep->rx_skbuff[i];
- fep->rx_skbuff[i] = NULL;
+ struct fec_enet_priv_tx_q *txq;
+ struct fec_enet_priv_rx_q *rxq;
+
+ rxq = fep->rx_queue[0];
+ bdp = rxq->rx_bd_base;
+ for (i = 0; i < rxq->rx_ring_size; i++) {
+ skb = rxq->rx_skbuff[i];
+ rxq->rx_skbuff[i] = NULL;
if (skb) {
dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr,
FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE);
dev_kfree_skb(skb);
}
- bdp = fec_enet_get_nextdesc(bdp, fep);
+ bdp = fec_enet_get_nextdesc(bdp, fep, 0);
}
- bdp = fep->tx_bd_base;
- for (i = 0; i < fep->tx_ring_size; i++) {
- kfree(fep->tx_bounce[i]);
- fep->tx_bounce[i] = NULL;
- skb = fep->tx_skbuff[i];
- fep->tx_skbuff[i] = NULL;
+ txq = fep->tx_queue[0];
+ bdp = txq->tx_bd_base;
+ for (i = 0; i < txq->tx_ring_size; i++) {
+ kfree(txq->tx_bounce[i]);
+ txq->tx_bounce[i] = NULL;
+ skb = txq->tx_skbuff[i];
+ txq->tx_skbuff[i] = NULL;
dev_kfree_skb(skb);
}
}
@@ -2161,9 +2264,12 @@ static int fec_enet_alloc_buffers(struct net_device *ndev)
unsigned int i;
struct sk_buff *skb;
struct bufdesc *bdp;
+ struct fec_enet_priv_tx_q *txq;
+ struct fec_enet_priv_rx_q *rxq;
- bdp = fep->rx_bd_base;
- for (i = 0; i < fep->rx_ring_size; i++) {
+ rxq = fep->rx_queue[0];
+ bdp = rxq->rx_bd_base;
+ for (i = 0; i < rxq->rx_ring_size; i++) {
dma_addr_t addr;
skb = netdev_alloc_skb(ndev, FEC_ENET_RX_FRSIZE);
@@ -2179,7 +2285,7 @@ static int fec_enet_alloc_buffers(struct net_device *ndev)
goto err_alloc;
}
- fep->rx_skbuff[i] = skb;
+ rxq->rx_skbuff[i] = skb;
bdp->cbd_bufaddr = addr;
bdp->cbd_sc = BD_ENET_RX_EMPTY;
@@ -2188,17 +2294,18 @@ static int fec_enet_alloc_buffers(struct net_device *ndev)
ebdp->cbd_esc = BD_ENET_RX_INT;
}
- bdp = fec_enet_get_nextdesc(bdp, fep);
+ bdp = fec_enet_get_nextdesc(bdp, fep, 0);
}
/* Set the last buffer to wrap. */
- bdp = fec_enet_get_prevdesc(bdp, fep);
+ bdp = fec_enet_get_prevdesc(bdp, fep, 0);
bdp->cbd_sc |= BD_SC_WRAP;
- bdp = fep->tx_bd_base;
- for (i = 0; i < fep->tx_ring_size; i++) {
- fep->tx_bounce[i] = kmalloc(FEC_ENET_TX_FRSIZE, GFP_KERNEL);
- if (!fep->tx_bounce[i])
+ txq = fep->tx_queue[0];
+ bdp = txq->tx_bd_base;
+ for (i = 0; i < txq->tx_ring_size; i++) {
+ txq->tx_bounce[i] = kmalloc(FEC_ENET_TX_FRSIZE, GFP_KERNEL);
+ if (!txq->tx_bounce[i])
goto err_alloc;
bdp->cbd_sc = 0;
@@ -2209,11 +2316,11 @@ static int fec_enet_alloc_buffers(struct net_device *ndev)
ebdp->cbd_esc = BD_ENET_TX_INT;
}
- bdp = fec_enet_get_nextdesc(bdp, fep);
+ bdp = fec_enet_get_nextdesc(bdp, fep, 0);
}
/* Set the last buffer to wrap. */
- bdp = fec_enet_get_prevdesc(bdp, fep);
+ bdp = fec_enet_get_prevdesc(bdp, fep, 0);
bdp->cbd_sc |= BD_SC_WRAP;
return 0;
@@ -2252,7 +2359,8 @@ fec_enet_open(struct net_device *ndev)
fec_restart(ndev);
napi_enable(&fep->napi);
phy_start(fep->phy_dev);
- netif_start_queue(ndev);
+ netif_tx_start_all_queues(ndev);
+
return 0;
}
@@ -2426,7 +2534,7 @@ static int fec_set_features(struct net_device *netdev,
/* Resume the device after updates */
if (netif_running(netdev) && changed & FEATURES_NEED_QUIESCE) {
fec_restart(netdev);
- netif_wake_queue(netdev);
+ netif_tx_wake_all_queues(netdev);
netif_tx_unlock_bh(netdev);
napi_enable(&fep->napi);
}
@@ -2434,10 +2542,17 @@ static int fec_set_features(struct net_device *netdev,
return 0;
}
+u16 fec_enet_select_queue(struct net_device *ndev, struct sk_buff *skb,
+ void *accel_priv, select_queue_fallback_t fallback)
+{
+ return skb_tx_hash(ndev, skb);
+}
+
static const struct net_device_ops fec_netdev_ops = {
.ndo_open = fec_enet_open,
.ndo_stop = fec_enet_close,
.ndo_start_xmit = fec_enet_start_xmit,
+ .ndo_select_queue = fec_enet_select_queue,
.ndo_set_rx_mode = set_multicast_list,
.ndo_change_mtu = eth_change_mtu,
.ndo_validate_addr = eth_validate_addr,
@@ -2459,39 +2574,60 @@ static int fec_enet_init(struct net_device *ndev)
struct fec_enet_private *fep = netdev_priv(ndev);
const struct platform_device_id *id_entry =
platform_get_device_id(fep->pdev);
+ struct fec_enet_priv_tx_q *txq;
+ struct fec_enet_priv_rx_q *rxq;
struct bufdesc *cbd_base;
+ dma_addr_t bd_dma;
int bd_size;
- /* init the tx & rx ring size */
- fep->tx_ring_size = TX_RING_SIZE;
- fep->rx_ring_size = RX_RING_SIZE;
+ txq = kzalloc(sizeof(*txq), GFP_KERNEL);
+ if (!txq)
+ return -ENOMEM;
+ fep->tx_queue[0] = txq;
+
+ rxq = kzalloc(sizeof(*rxq), GFP_KERNEL);
+ if (!rxq) {
+ kfree(txq);
+ return -ENOMEM;
+ }
+
+ fep->rx_queue[0] = rxq;
- fep->tx_stop_threshold = FEC_MAX_SKB_DESCS;
- fep->tx_wake_threshold = (fep->tx_ring_size - fep->tx_stop_threshold) / 2;
+
+ txq->tx_ring_size = TX_RING_SIZE;
+ rxq->rx_ring_size = RX_RING_SIZE;
+ fep->total_tx_ring_size = txq->tx_ring_size;
+ fep->total_rx_ring_size = rxq->rx_ring_size;
+
+ txq->tx_stop_threshold = FEC_MAX_SKB_DESCS;
+ txq->tx_wake_threshold = (txq->tx_ring_size - txq->tx_stop_threshold) / 2;
if (fep->bufdesc_ex)
fep->bufdesc_size = sizeof(struct bufdesc_ex);
else
fep->bufdesc_size = sizeof(struct bufdesc);
- bd_size = (fep->tx_ring_size + fep->rx_ring_size) *
+ bd_size = (fep->total_tx_ring_size + fep->total_rx_ring_size) *
fep->bufdesc_size;
/* Allocate memory for buffer descriptors. */
- cbd_base = dma_alloc_coherent(NULL, bd_size, &fep->bd_dma,
+ cbd_base = dma_alloc_coherent(NULL, bd_size, &bd_dma,
GFP_KERNEL);
- if (!cbd_base)
+ if (!cbd_base) {
+ kfree(rxq);
+ kfree(txq);
return -ENOMEM;
+ }
- fep->tso_hdrs = dma_alloc_coherent(NULL, fep->tx_ring_size * TSO_HEADER_SIZE,
- &fep->tso_hdrs_dma, GFP_KERNEL);
- if (!fep->tso_hdrs) {
- dma_free_coherent(NULL, bd_size, cbd_base, fep->bd_dma);
+ txq->tso_hdrs = dma_alloc_coherent(NULL, txq->tx_ring_size * TSO_HEADER_SIZE,
+ &txq->tso_hdrs_dma, GFP_KERNEL);
+ if (!txq->tso_hdrs) {
+ kfree(rxq);
+ kfree(txq);
+ dma_free_coherent(NULL, bd_size, cbd_base, bd_dma);
return -ENOMEM;
}
- memset(cbd_base, 0, PAGE_SIZE);
-
- fep->netdev = ndev;
+ memset(cbd_base, 0, bd_size);
/* Get the Ethernet address */
fec_get_mac(ndev);
@@ -2499,12 +2635,13 @@ static int fec_enet_init(struct net_device *ndev)
fec_set_mac_address(ndev, NULL);
/* Set receive and transmit descriptor base. */
- fep->rx_bd_base = cbd_base;
+ rxq->rx_bd_base = cbd_base;
if (fep->bufdesc_ex)
- fep->tx_bd_base = (struct bufdesc *)
- (((struct bufdesc_ex *)cbd_base) + fep->rx_ring_size);
+ txq->tx_bd_base = (struct bufdesc *)
+ (((struct bufdesc_ex *)cbd_base) + rxq->rx_ring_size);
else
- fep->tx_bd_base = cbd_base + fep->rx_ring_size;
+ txq->tx_bd_base = cbd_base + rxq->rx_ring_size;
+
/* The FEC Ethernet specific entries in the device structure */
ndev->watchdog_timeo = TX_TIMEOUT;
--
1.9.1
^ permalink raw reply related
* [Patch v4 net-next 02/12] net:fec: add enet AVB feature macro define for imx6sx
From: Frank.Li @ 2014-09-12 21:00 UTC (permalink / raw)
To: b38611, davem, netdev, lznuaa
Cc: devicetree, Frank Li, Fugang Duan, linux, shawn.guo,
linux-arm-kernel
In-Reply-To: <1410555657-10744-1-git-send-email-Frank.Li@freescale.com>
From: Fugang Duan <B38611@freescale.com>
Add enet AVB feature macro define for imx6sx.
Signed-off-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Frank Li <Frank.Li@freescale.com>
---
drivers/net/ethernet/freescale/fec_main.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index c21ecff1..ee9f04f 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -104,6 +104,16 @@ static void set_multicast_list(struct net_device *ndev);
* ENET_TDAR[TDAR].
*/
#define FEC_QUIRK_ERR006358 (1 << 7)
+/* ENET IP hw AVB
+ *
+ * i.MX6SX ENET IP add Audio Video Bridging (AVB) feature support.
+ * - Two class indicators on receive with configurable priority
+ * - Two class indicators and line speed timer on transmit allowing
+ * implementation class credit based shapers externally
+ * - Additional DMA registers provisioned to allow managing up to 3
+ * independent rings
+ */
+#define FEC_QUIRK_HAS_AVB (1 << 8)
static struct platform_device_id fec_devtype[] = {
{
@@ -128,6 +138,12 @@ static struct platform_device_id fec_devtype[] = {
.name = "mvf600-fec",
.driver_data = FEC_QUIRK_ENET_MAC,
}, {
+ .name = "imx6sx-fec",
+ .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
+ FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
+ FEC_QUIRK_HAS_VLAN | FEC_QUIRK_ERR006358 |
+ FEC_QUIRK_HAS_AVB,
+ }, {
/* sentinel */
}
};
--
1.9.1
^ permalink raw reply related
* [Patch v4 net-next 01/12] net:fec: add enet refrence clock for i.MX 6SX chip
From: Frank.Li @ 2014-09-12 21:00 UTC (permalink / raw)
To: b38611, davem, netdev, lznuaa
Cc: devicetree, Frank Li, Fugang Duan, linux, shawn.guo,
linux-arm-kernel
In-Reply-To: <1410555657-10744-1-git-send-email-Frank.Li@freescale.com>
From: Fugang Duan <B38611@freescale.com>
i.MX6sx enet has below clocks for user config:
clk_ipg: ipg_clk_s, ipg_clk_mac0_s, 66Mhz
clk_ahb: enet system clock, it is enet AXI clock for imx6sx.
For imx6sx, it alos is the clock source of interrupt coalescing.
The clock range: 200Mhz ~ 266Mhz.
clk_ref: refrence clock for tx and rx. For imx6sx enet RGMII mode,
the refrence clock is 125Mhz coming from internal PLL or external.
In i.MX6sx-arm2 board, the clock is from internal PLL.
clk_ref is optional, depends on board.
clk_enet_out: The clock can be output from internal PLL. It can supply 50Mhz
clock for phy. clk_enet_out is optional, depends on chip and board.
clk_ptp: 1588 ts clock. It is optional, depends on chip.
The patch add clk_ref to distiguish the different clocks.
Signed-off-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Frank Li <Frank.Li@freescale.com>
---
drivers/net/ethernet/freescale/fec.h | 1 +
drivers/net/ethernet/freescale/fec_main.c | 17 +++++++++++++++++
2 files changed, 18 insertions(+)
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index ee41d98..635772b 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -272,6 +272,7 @@ struct fec_enet_private {
struct clk *clk_ipg;
struct clk *clk_ahb;
+ struct clk *clk_ref;
struct clk *clk_enet_out;
struct clk *clk_ptp;
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 89355a7..c21ecff1 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1621,6 +1621,11 @@ static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
}
mutex_unlock(&fep->ptp_clk_mutex);
}
+ if (fep->clk_ref) {
+ ret = clk_prepare_enable(fep->clk_ref);
+ if (ret)
+ goto failed_clk_ref;
+ }
} else {
clk_disable_unprepare(fep->clk_ahb);
clk_disable_unprepare(fep->clk_ipg);
@@ -1632,9 +1637,15 @@ static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
fep->ptp_clk_on = false;
mutex_unlock(&fep->ptp_clk_mutex);
}
+ if (fep->clk_ref)
+ clk_disable_unprepare(fep->clk_ref);
}
return 0;
+
+failed_clk_ref:
+ if (fep->clk_ref)
+ clk_disable_unprepare(fep->clk_ref);
failed_clk_ptp:
if (fep->clk_enet_out)
clk_disable_unprepare(fep->clk_enet_out);
@@ -2637,6 +2648,12 @@ fec_probe(struct platform_device *pdev)
fep->ptp_clk_on = false;
mutex_init(&fep->ptp_clk_mutex);
+
+ /* clk_ref is optional, depends on board */
+ fep->clk_ref = devm_clk_get(&pdev->dev, "enet_clk_ref");
+ if (IS_ERR(fep->clk_ref))
+ fep->clk_ref = NULL;
+
fep->clk_ptp = devm_clk_get(&pdev->dev, "ptp");
fep->bufdesc_ex =
pdev->id_entry->driver_data & FEC_QUIRK_HAS_BUFDESC_EX;
--
1.9.1
^ permalink raw reply related
* Re: [net-next PATCH v5 13/16] net: sched: make tc_action safe to walk under RCU
From: Eric Dumazet @ 2014-09-12 20:51 UTC (permalink / raw)
To: John Fastabend; +Cc: xiyou.wangcong, davem, jhs, netdev, paulmck, brouer
In-Reply-To: <20140912163403.19588.26443.stgit@nitbit.x32>
On Fri, 2014-09-12 at 09:34 -0700, John Fastabend wrote:
> Second there is a suspect usage of list_splice_init_rcu() in the
> tcf_exts_change() routine. Notice how it is used twice in succession
> and the second init works on the src tcf_exts. There is probably a
> better way to accomplish that.
>
> +/* It is not safe to use src->actions after this due to _init_rcu usage
> + * INIT_LIST_HEAD_RCU() is called on src->actions
> + */
> void tcf_exts_change(struct tcf_proto *tp, struct tcf_exts *dst,
> struct tcf_exts *src)
> {
> #ifdef CONFIG_NET_CLS_ACT
> LIST_HEAD(tmp);
> - tcf_tree_lock(tp);
> - list_splice_init(&dst->actions, &tmp);
> - list_splice(&src->actions, &dst->actions);
> - tcf_tree_unlock(tp);
> + list_splice_init_rcu(&dst->actions, &tmp, synchronize_rcu);
> + list_splice_init_rcu(&src->actions,
> + &dst->actions,
> + synchronize_rcu);
> tcf_action_destroy(&tmp, TCA_ACT_UNBIND);
> #endif
> }
I am afraid I do not understand this part.
^ permalink raw reply
* [PATCH NEXT] rtlwifi: btcoexist: Change local debugging macros CL_*** into the standard varieties
From: Larry Finger @ 2014-09-12 20:50 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Larry Finger, netdev
Macros CL_SNPRINTF and CL_PRINTF are always used in that order. The first
formats info into a buffer, and the second dumps it with printk. As the
debug system in rtlwifi has a macro that does this with a single call,
it seems reasonable to use it instead. An additional benefit is that the
debug level can be set when loading the driver used by the wifi device.
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
---
.../wireless/rtlwifi/btcoexist/halbtc8192e2ant.c | 119 +++++++-------------
.../wireless/rtlwifi/btcoexist/halbtc8723b1ant.c | 125 +++++++--------------
.../wireless/rtlwifi/btcoexist/halbtc8723b2ant.c | 105 ++++++-----------
.../wireless/rtlwifi/btcoexist/halbtc8821a1ant.c | 122 +++++++-------------
.../wireless/rtlwifi/btcoexist/halbtc8821a2ant.c | 107 ++++++------------
.../net/wireless/rtlwifi/btcoexist/halbtcoutsrc.c | 3 -
.../net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h | 4 -
7 files changed, 194 insertions(+), 391 deletions(-)
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8192e2ant.c b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8192e2ant.c
index af3f604..53261d6 100644
--- a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8192e2ant.c
+++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8192e2ant.c
@@ -3305,7 +3305,7 @@ void ex_halbtc8192e2ant_display_coex_info(struct btc_coexist *btcoexist)
{
struct btc_board_info *board_info = &btcoexist->board_info;
struct btc_stack_info *stack_info = &btcoexist->stack_info;
- u8 *cli_buf = btcoexist->cli_buf;
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
u8 u8tmp[4], i, bt_info_ext, ps_tdma_case = 0;
u16 u16tmp[4];
u32 u32tmp[4];
@@ -3316,87 +3316,75 @@ void ex_halbtc8192e2ant_display_coex_info(struct btc_coexist *btcoexist)
u8 wifi_dot11_chnl, wifi_hs_chnl;
u32 fw_ver = 0, bt_patch_ver = 0;
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n ============[BT Coexist info]============");
- CL_PRINTF(cli_buf);
if (btcoexist->manual_control) {
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n ===========[Under Manual Control]===========");
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n ==========================================");
- CL_PRINTF(cli_buf);
}
if (!board_info->bt_exist) {
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n BT not exists !!!");
- CL_PRINTF(cli_buf);
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n BT not exists !!!");
return;
}
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %d/ %d ", "Ant PG number/ Ant mechanism:",
board_info->pg_ant_num, board_info->btdm_ant_num);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %d",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s / %d",
"BT stack/ hci ext ver",
((stack_info->profile_notified) ? "Yes" : "No"),
stack_info->hci_version);
- CL_PRINTF(cli_buf);
btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER, &bt_patch_ver);
btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %d_%d/ 0x%x/ 0x%x(%d)",
"CoexVer/ FwVer/ PatchVer",
glcoex_ver_date_8192e_2ant, glcoex_ver_8192e_2ant,
fw_ver, bt_patch_ver, bt_patch_ver);
- CL_PRINTF(cli_buf);
btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hson);
btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_DOT11_CHNL,
&wifi_dot11_chnl);
btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifi_hs_chnl);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d(%d)",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d / %d(%d)",
"Dot11 channel / HsMode(HsChnl)",
wifi_dot11_chnl, bt_hson, wifi_hs_chnl);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x ",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %02x %02x %02x ",
"H2C Wifi inform bt chnl Info", coex_dm->wifi_chnl_info[0],
coex_dm->wifi_chnl_info[1], coex_dm->wifi_chnl_info[2]);
- CL_PRINTF(cli_buf);
btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifirssi);
btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d",
"Wifi rssi/ HS rssi", wifirssi, bt_hs_rssi);
- CL_PRINTF(cli_buf);
btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan);
btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link);
btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d/ %d ",
"Wifi link/ roam/ scan", link, roam, scan);
- CL_PRINTF(cli_buf);
btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION,
&wifi_traffic_dir);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %s/ %s ",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s / %s/ %s ",
"Wifi status", (wifi_under_5g ? "5G" : "2.4G"),
((BTC_WIFI_BW_LEGACY == wifi_bw) ? "Legacy" :
(((BTC_WIFI_BW_HT40 == wifi_bw) ? "HT40" : "HT20"))),
((!wifi_busy) ? "idle" :
((BTC_WIFI_TRAFFIC_TX == wifi_traffic_dir) ?
"uplink" : "downlink")));
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = [%s/ %d/ %d] ",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = [%s/ %d/ %d] ",
"BT [status/ rssi/ retryCnt]",
((btcoexist->bt_info.bt_disabled) ? ("disabled") :
((coex_sta->c2h_bt_inquiry_page) ?
@@ -3406,166 +3394,139 @@ void ex_halbtc8192e2ant_display_coex_info(struct btc_coexist *btcoexist)
((BT_8192E_2ANT_BT_STATUS_CONNECTED_IDLE ==
coex_dm->bt_status) ? "connected-idle" : "busy")))),
coex_sta->bt_rssi, coex_sta->bt_retry_cnt);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d / %d / %d",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d / %d / %d / %d",
"SCO/HID/PAN/A2DP", stack_info->sco_exist,
stack_info->hid_exist, stack_info->pan_exist,
stack_info->a2dp_exist);
- CL_PRINTF(cli_buf);
btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_BT_LINK_INFO);
bt_info_ext = coex_sta->bt_info_ext;
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s",
"BT Info A2DP rate",
(bt_info_ext&BIT0) ? "Basic rate" : "EDR rate");
- CL_PRINTF(cli_buf);
for (i = 0; i < BT_INFO_SRC_8192E_2ANT_MAX; i++) {
if (coex_sta->bt_info_c2h_cnt[i]) {
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %02x %02x %02x %02x ",
GLBtInfoSrc8192e2Ant[i],
coex_sta->bt_info_c2h[i][0],
coex_sta->bt_info_c2h[i][1],
coex_sta->bt_info_c2h[i][2],
coex_sta->bt_info_c2h[i][3]);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"%02x %02x %02x(%d)",
coex_sta->bt_info_c2h[i][4],
coex_sta->bt_info_c2h[i][5],
coex_sta->bt_info_c2h[i][6],
coex_sta->bt_info_c2h_cnt[i]);
- CL_PRINTF(cli_buf);
}
}
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/%s",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s/%s",
"PS state, IPS/LPS",
((coex_sta->under_ips ? "IPS ON" : "IPS OFF")),
((coex_sta->under_lps ? "LPS ON" : "LPS OFF")));
- CL_PRINTF(cli_buf);
btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x ", "SS Type",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x ", "SS Type",
coex_dm->cur_sstype);
- CL_PRINTF(cli_buf);
/* Sw mechanism */
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s",
"============[Sw mechanism]============");
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d/ %d ",
"SM1[ShRf/ LpRA/ LimDig]", coex_dm->cur_rf_rx_lpf_shrink,
coex_dm->cur_low_penalty_ra, coex_dm->limited_dig);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d(0x%x) ",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d/ %d(0x%x) ",
"SM2[AgcT/ AdcB/ SwDacSwing(lvl)]",
coex_dm->cur_agc_table_en, coex_dm->cur_adc_back_off,
coex_dm->cur_dac_swing_on, coex_dm->cur_dac_swing_lvl);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x ", "Rate Mask",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x ", "Rate Mask",
btcoexist->bt_info.ra_mask);
- CL_PRINTF(cli_buf);
/* Fw mechanism */
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s",
"============[Fw mechanism]============");
- CL_PRINTF(cli_buf);
ps_tdma_case = coex_dm->cur_ps_tdma;
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %02x %02x %02x %02x %02x case-%d (auto:%d)",
"PS TDMA", coex_dm->ps_tdma_para[0],
coex_dm->ps_tdma_para[1], coex_dm->ps_tdma_para[2],
coex_dm->ps_tdma_para[3], coex_dm->ps_tdma_para[4],
ps_tdma_case, coex_dm->auto_tdma_adjust);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d ",
"DecBtPwr/ IgnWlanAct",
coex_dm->cur_dec_bt_pwr, coex_dm->cur_ignore_wlan_act);
- CL_PRINTF(cli_buf);
/* Hw setting */
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s",
"============[Hw setting]============");
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x",
"RF-A, 0x1e initVal", coex_dm->bt_rf0x1e_backup);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/0x%x/0x%x/0x%x",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/0x%x/0x%x/0x%x",
"backup ARFR1/ARFR2/RL/AMaxTime", coex_dm->backup_arfr_cnt1,
coex_dm->backup_arfr_cnt2, coex_dm->backup_retrylimit,
coex_dm->backup_ampdu_maxtime);
- CL_PRINTF(cli_buf);
u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x430);
u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x434);
u16tmp[0] = btcoexist->btc_read_2byte(btcoexist, 0x42a);
u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x456);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/0x%x/0x%x/0x%x",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/0x%x/0x%x/0x%x",
"0x430/0x434/0x42a/0x456",
u32tmp[0], u32tmp[1], u16tmp[0], u8tmp[0]);
- CL_PRINTF(cli_buf);
u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc04);
u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0xd04);
u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x90c);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
"0xc04/ 0xd04/ 0x90c", u32tmp[0], u32tmp[1], u32tmp[2]);
- CL_PRINTF(cli_buf);
u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x778);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x778",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x", "0x778",
u8tmp[0]);
- CL_PRINTF(cli_buf);
u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x92c);
u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x930);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x",
"0x92c/ 0x930", (u8tmp[0]), u32tmp[0]);
- CL_PRINTF(cli_buf);
u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x40);
u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x4f);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x",
"0x40/ 0x4f", u8tmp[0], u8tmp[1]);
- CL_PRINTF(cli_buf);
u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x550);
u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x522);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x",
"0x550(bcn ctrl)/0x522", u32tmp[0], u8tmp[0]);
- CL_PRINTF(cli_buf);
u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc50);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0xc50(dig)",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x", "0xc50(dig)",
u32tmp[0]);
- CL_PRINTF(cli_buf);
u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6c0);
u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x6c4);
u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x6c8);
u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x6cc);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x",
"0x6c0/0x6c4/0x6c8/0x6cc(coexTable)",
u32tmp[0], u32tmp[1], u32tmp[2], u8tmp[0]);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d",
"0x770(hp rx[31:16]/tx[15:0])",
coex_sta->high_priority_rx, coex_sta->high_priority_tx);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d",
"0x774(lp rx[31:16]/tx[15:0])",
coex_sta->low_priority_rx, coex_sta->low_priority_tx);
- CL_PRINTF(cli_buf);
#if (BT_AUTO_REPORT_ONLY_8192E_2ANT == 1)
halbtc8192e2ant_monitor_bt_ctr(btcoexist);
#endif
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b1ant.c b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b1ant.c
index e4948c8..c4acd40 100644
--- a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b1ant.c
+++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b1ant.c
@@ -2398,7 +2398,7 @@ void ex_halbtc8723b1ant_display_coex_info(struct btc_coexist *btcoexist)
struct btc_board_info *board_info = &btcoexist->board_info;
struct btc_stack_info *stack_info = &btcoexist->stack_info;
struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
- u8 *cli_buf = btcoexist->cli_buf;
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
u8 u8tmp[4], i, bt_info_ext, pstdmacase = 0;
u16 u16tmp[4];
u32 u32tmp[4];
@@ -2410,81 +2410,68 @@ void ex_halbtc8723b1ant_display_coex_info(struct btc_coexist *btcoexist)
u8 wifi_dot11_chnl, wifi_hs_chnl;
u32 fw_ver = 0, bt_patch_ver = 0;
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n ============[BT Coexist info]============");
- CL_PRINTF(cli_buf);
if (btcoexist->manual_control) {
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n ============[Under Manual Control]==========");
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n ==========================================");
- CL_PRINTF(cli_buf);
}
if (btcoexist->stop_coex_dm) {
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n ============[Coex is STOPPED]============");
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n ==========================================");
- CL_PRINTF(cli_buf);
}
if (!board_info->bt_exist) {
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n BT not exists !!!");
- CL_PRINTF(cli_buf);
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n BT not exists !!!");
return;
}
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d/ %d",
"Ant PG Num/ Ant Mech/ Ant Pos:",
board_info->pg_ant_num, board_info->btdm_ant_num,
board_info->btdm_ant_pos);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %d",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s / %d",
"BT stack/ hci ext ver",
((stack_info->profile_notified) ? "Yes" : "No"),
stack_info->hci_version);
- CL_PRINTF(cli_buf);
btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER, &bt_patch_ver);
btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %d_%x/ 0x%x/ 0x%x(%d)",
"CoexVer/ FwVer/ PatchVer",
glcoex_ver_date_8723b_1ant, glcoex_ver_8723b_1ant,
fw_ver, bt_patch_ver, bt_patch_ver);
- CL_PRINTF(cli_buf);
btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_DOT11_CHNL,
&wifi_dot11_chnl);
btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifi_hs_chnl);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d(%d)",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d / %d(%d)",
"Dot11 channel / HsChnl(HsMode)",
wifi_dot11_chnl, wifi_hs_chnl, bt_hs_on);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x ",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %02x %02x %02x ",
"H2C Wifi inform bt chnl Info",
coex_dm->wifi_chnl_info[0], coex_dm->wifi_chnl_info[1],
coex_dm->wifi_chnl_info[2]);
- CL_PRINTF(cli_buf);
btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi);
btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d",
"Wifi rssi/ HS rssi", wifi_rssi, bt_hs_rssi);
- CL_PRINTF(cli_buf);
btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan);
btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link);
btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d/ %d ",
"Wifi link/ roam/ scan", link, roam, scan);
- CL_PRINTF(cli_buf);
btcoexist->btc_get(btcoexist , BTC_GET_BL_WIFI_UNDER_5G,
&wifi_under_5g);
@@ -2493,27 +2480,25 @@ void ex_halbtc8723b1ant_display_coex_info(struct btc_coexist *btcoexist)
btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION,
&wifi_traffic_dir);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %s/ %s ",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s / %s/ %s ",
"Wifi status", (wifi_under_5g ? "5G" : "2.4G"),
((BTC_WIFI_BW_LEGACY == wifi_bw) ? "Legacy" :
(((BTC_WIFI_BW_HT40 == wifi_bw) ? "HT40" : "HT20"))),
((!wifi_busy) ? "idle" :
((BTC_WIFI_TRAFFIC_TX == wifi_traffic_dir) ?
"uplink" : "downlink")));
- CL_PRINTF(cli_buf);
btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS,
&wifi_link_status);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d/ %d/ %d",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d/ %d/ %d/ %d",
"sta/vwifi/hs/p2pGo/p2pGc",
((wifi_link_status & WIFI_STA_CONNECTED) ? 1 : 0),
((wifi_link_status & WIFI_AP_CONNECTED) ? 1 : 0),
((wifi_link_status & WIFI_HS_CONNECTED) ? 1 : 0),
((wifi_link_status & WIFI_P2P_GO_CONNECTED) ? 1 : 0),
((wifi_link_status & WIFI_P2P_GC_CONNECTED) ? 1 : 0));
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = [%s/ %d/ %d] ",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = [%s/ %d/ %d] ",
"BT [status/ rssi/ retryCnt]",
((btcoexist->bt_info.bt_disabled) ? ("disabled") :
((coex_sta->c2h_bt_inquiry_page) ? ("inquiry/page scan") :
@@ -2524,25 +2509,22 @@ void ex_halbtc8723b1ant_display_coex_info(struct btc_coexist *btcoexist)
coex_dm->bt_status) ?
"connected-idle" : "busy")))),
coex_sta->bt_rssi, coex_sta->bt_retry_cnt);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %d / %d / %d / %d",
"SCO/HID/PAN/A2DP", bt_link_info->sco_exist,
bt_link_info->hid_exist, bt_link_info->pan_exist,
bt_link_info->a2dp_exist);
- CL_PRINTF(cli_buf);
btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_BT_LINK_INFO);
bt_info_ext = coex_sta->bt_info_ext;
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s",
"BT Info A2DP rate",
(bt_info_ext & BIT0) ? "Basic rate" : "EDR rate");
- CL_PRINTF(cli_buf);
for (i = 0; i < BT_INFO_SRC_8723B_1ANT_MAX; i++) {
if (coex_sta->bt_info_c2h_cnt[i]) {
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %02x %02x %02x %02x %02x %02x %02x(%d)",
GLBtInfoSrc8723b1Ant[i],
coex_sta->bt_info_c2h[i][0],
@@ -2553,130 +2535,111 @@ void ex_halbtc8723b1ant_display_coex_info(struct btc_coexist *btcoexist)
coex_sta->bt_info_c2h[i][5],
coex_sta->bt_info_c2h[i][6],
coex_sta->bt_info_c2h_cnt[i]);
- CL_PRINTF(cli_buf);
}
}
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %s/%s, (0x%x/0x%x)",
"PS state, IPS/LPS, (lps/rpwm)",
((coex_sta->under_ips ? "IPS ON" : "IPS OFF")),
((coex_sta->under_lps ? "LPS ON" : "LPS OFF")),
btcoexist->bt_info.lps_val,
btcoexist->bt_info.rpwm_val);
- CL_PRINTF(cli_buf);
btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD);
if (!btcoexist->manual_control) {
/* Sw mechanism */
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s",
"============[Sw mechanism]============");
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/",
"SM[LowPenaltyRA]", coex_dm->cur_low_penalty_ra);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %s/ %d ",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s/ %s/ %d ",
"DelBA/ BtCtrlAgg/ AggSize",
(btcoexist->bt_info.reject_agg_pkt ? "Yes" : "No"),
(btcoexist->bt_info.bt_ctrl_buf_size ? "Yes" : "No"),
btcoexist->bt_info.agg_buf_size);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x ",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x ",
"Rate Mask", btcoexist->bt_info.ra_mask);
- CL_PRINTF(cli_buf);
/* Fw mechanism */
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s",
"============[Fw mechanism]============");
- CL_PRINTF(cli_buf);
pstdmacase = coex_dm->cur_ps_tdma;
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %02x %02x %02x %02x %02x case-%d (auto:%d)",
"PS TDMA", coex_dm->ps_tdma_para[0],
coex_dm->ps_tdma_para[1], coex_dm->ps_tdma_para[2],
coex_dm->ps_tdma_para[3], coex_dm->ps_tdma_para[4],
pstdmacase, coex_dm->auto_tdma_adjust);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d ",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d ",
"IgnWlanAct", coex_dm->cur_ignore_wlan_act);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x ",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x ",
"Latest error condition(should be 0)",
coex_dm->error_condition);
- CL_PRINTF(cli_buf);
}
/* Hw setting */
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s",
"============[Hw setting]============");
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/0x%x/0x%x/0x%x",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/0x%x/0x%x/0x%x",
"backup ARFR1/ARFR2/RL/AMaxTime", coex_dm->backup_arfr_cnt1,
coex_dm->backup_arfr_cnt2, coex_dm->backup_retry_limit,
coex_dm->backup_ampdu_max_time);
- CL_PRINTF(cli_buf);
u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x430);
u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x434);
u16tmp[0] = btcoexist->btc_read_2byte(btcoexist, 0x42a);
u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x456);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/0x%x/0x%x/0x%x",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/0x%x/0x%x/0x%x",
"0x430/0x434/0x42a/0x456",
u32tmp[0], u32tmp[1], u16tmp[0], u8tmp[0]);
- CL_PRINTF(cli_buf);
u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x778);
u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6cc);
u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x880);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
"0x778/0x6cc/0x880[29:25]", u8tmp[0], u32tmp[0],
(u32tmp[1] & 0x3e000000) >> 25);
- CL_PRINTF(cli_buf);
u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x948);
u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x67);
u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x765);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
"0x948/ 0x67[5] / 0x765",
u32tmp[0], ((u8tmp[0] & 0x20) >> 5), u8tmp[1]);
- CL_PRINTF(cli_buf);
u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x92c);
u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x930);
u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x944);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
"0x92c[1:0]/ 0x930[7:0]/0x944[1:0]",
u32tmp[0] & 0x3, u32tmp[1] & 0xff, u32tmp[2] & 0x3);
- CL_PRINTF(cli_buf);
u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x39);
u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x40);
u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x4c);
u8tmp[2] = btcoexist->btc_read_1byte(btcoexist, 0x64);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x",
"0x38[11]/0x40/0x4c[24:23]/0x64[0]",
((u8tmp[0] & 0x8)>>3), u8tmp[1],
((u32tmp[0] & 0x01800000) >> 23), u8tmp[2] & 0x1);
- CL_PRINTF(cli_buf);
u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x550);
u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x522);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x",
"0x550(bcn ctrl)/0x522", u32tmp[0], u8tmp[0]);
- CL_PRINTF(cli_buf);
u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc50);
u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x49c);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x",
"0xc50(dig)/0x49c(null-drop)", u32tmp[0] & 0xff, u8tmp[0]);
- CL_PRINTF(cli_buf);
u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xda0);
u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0xda4);
@@ -2694,27 +2657,23 @@ void ex_halbtc8723b1ant_display_coex_info(struct btc_coexist *btcoexist)
(u32tmp[3] & 0xffff);
fa_cck = (u8tmp[0] << 8) + u8tmp[1];
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
"OFDM-CCA/OFDM-FA/CCK-FA",
u32tmp[0] & 0xffff, fa_ofdm, fa_cck);
- CL_PRINTF(cli_buf);
u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6c0);
u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x6c4);
u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x6c8);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
"0x6c0/0x6c4/0x6c8(coexTable)",
u32tmp[0], u32tmp[1], u32tmp[2]);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d",
"0x770(high-pri rx/tx)", coex_sta->high_priority_rx,
coex_sta->high_priority_tx);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d",
"0x774(low-pri rx/tx)", coex_sta->low_priority_rx,
coex_sta->low_priority_tx);
- CL_PRINTF(cli_buf);
#if (BT_AUTO_REPORT_ONLY_8723B_1ANT == 1)
halbtc8723b1ant_monitor_bt_ctr(btcoexist);
#endif
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.c b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.c
index bd37d65..cefe269 100644
--- a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.c
+++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.c
@@ -3159,7 +3159,7 @@ void ex_btc8723b2ant_display_coex_info(struct btc_coexist *btcoexist)
struct btc_board_info *board_info = &btcoexist->board_info;
struct btc_stack_info *stack_info = &btcoexist->stack_info;
struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
- u8 *cli_buf = btcoexist->cli_buf;
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
u8 u8tmp[4], i, bt_info_ext, ps_tdma_case = 0;
u32 u32tmp[4];
bool roam = false, scan = false;
@@ -3171,106 +3171,91 @@ void ex_btc8723b2ant_display_coex_info(struct btc_coexist *btcoexist)
u32 fw_ver = 0, bt_patch_ver = 0;
u8 ap_num = 0;
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n ============[BT Coexist info]============");
- CL_PRINTF(cli_buf);
if (btcoexist->manual_control) {
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n ==========[Under Manual Control]============");
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n ==========================================");
- CL_PRINTF(cli_buf);
}
if (!board_info->bt_exist) {
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n BT not exists !!!");
- CL_PRINTF(cli_buf);
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n BT not exists !!!");
return;
}
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d ",
"Ant PG number/ Ant mechanism:",
board_info->pg_ant_num, board_info->btdm_ant_num);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %d",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s / %d",
"BT stack/ hci ext ver",
((stack_info->profile_notified) ? "Yes" : "No"),
stack_info->hci_version);
- CL_PRINTF(cli_buf);
btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER, &bt_patch_ver);
btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %d_%x/ 0x%x/ 0x%x(%d)",
"CoexVer/ FwVer/ PatchVer",
glcoex_ver_date_8723b_2ant, glcoex_ver_8723b_2ant,
fw_ver, bt_patch_ver, bt_patch_ver);
- CL_PRINTF(cli_buf);
btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_DOT11_CHNL,
&wifi_dot11_chnl);
btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifi_hs_chnl);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d(%d)",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d / %d(%d)",
"Dot11 channel / HsChnl(HsMode)",
wifi_dot11_chnl, wifi_hs_chnl, bt_hs_on);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x ",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %02x %02x %02x ",
"H2C Wifi inform bt chnl Info", coex_dm->wifi_chnl_info[0],
coex_dm->wifi_chnl_info[1], coex_dm->wifi_chnl_info[2]);
- CL_PRINTF(cli_buf);
btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi);
btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi);
btcoexist->btc_get(btcoexist, BTC_GET_U1_AP_NUM, &ap_num);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d/ %d",
"Wifi rssi/ HS rssi/ AP#", wifi_rssi, bt_hs_rssi, ap_num);
- CL_PRINTF(cli_buf);
btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan);
btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link);
btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d/ %d ",
"Wifi link/ roam/ scan", link, roam, scan);
- CL_PRINTF(cli_buf);
btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION,
&wifi_traffic_dir);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %s/ %s ",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s / %s/ %s ",
"Wifi status", (wifi_under_5g ? "5G" : "2.4G"),
((BTC_WIFI_BW_LEGACY == wifi_bw) ? "Legacy" :
(((BTC_WIFI_BW_HT40 == wifi_bw) ? "HT40" : "HT20"))),
((!wifi_busy) ? "idle" :
((BTC_WIFI_TRAFFIC_TX == wifi_traffic_dir) ?
"uplink" : "downlink")));
- CL_PRINTF(cli_buf);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d / %d / %d",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d / %d / %d / %d",
"SCO/HID/PAN/A2DP",
bt_link_info->sco_exist, bt_link_info->hid_exist,
bt_link_info->pan_exist, bt_link_info->a2dp_exist);
- CL_PRINTF(cli_buf);
btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_BT_LINK_INFO);
bt_info_ext = coex_sta->bt_info_ext;
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s",
"BT Info A2DP rate",
(bt_info_ext&BIT0) ? "Basic rate" : "EDR rate");
- CL_PRINTF(cli_buf);
for (i = 0; i < BT_INFO_SRC_8723B_2ANT_MAX; i++) {
if (coex_sta->bt_info_c2h_cnt[i]) {
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %02x %02x %02x "
"%02x %02x %02x %02x(%d)",
glbt_info_src_8723b_2ant[i],
@@ -3282,104 +3267,88 @@ void ex_btc8723b2ant_display_coex_info(struct btc_coexist *btcoexist)
coex_sta->bt_info_c2h[i][5],
coex_sta->bt_info_c2h[i][6],
coex_sta->bt_info_c2h_cnt[i]);
- CL_PRINTF(cli_buf);
}
}
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/%s",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s/%s",
"PS state, IPS/LPS",
((coex_sta->under_ips ? "IPS ON" : "IPS OFF")),
((coex_sta->under_lps ? "LPS ON" : "LPS OFF")));
- CL_PRINTF(cli_buf);
btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD);
/* Sw mechanism */
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s", "============[Sw mechanism]============");
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d/ %d ",
"SM1[ShRf/ LpRA/ LimDig]", coex_dm->cur_rf_rx_lpf_shrink,
coex_dm->cur_low_penalty_ra, coex_dm->limited_dig);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d(0x%x) ",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d/ %d(0x%x) ",
"SM2[AgcT/ AdcB/ SwDacSwing(lvl)]",
coex_dm->cur_agc_table_en, coex_dm->cur_adc_back_off,
coex_dm->cur_dac_swing_on, coex_dm->cur_dac_swing_lvl);
- CL_PRINTF(cli_buf);
/* Fw mechanism */
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s",
"============[Fw mechanism]============");
- CL_PRINTF(cli_buf);
ps_tdma_case = coex_dm->cur_ps_tdma;
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %02x %02x %02x %02x %02x case-%d (auto:%d)",
"PS TDMA", coex_dm->ps_tdma_para[0],
coex_dm->ps_tdma_para[1], coex_dm->ps_tdma_para[2],
coex_dm->ps_tdma_para[3], coex_dm->ps_tdma_para[4],
ps_tdma_case, coex_dm->auto_tdma_adjust);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d ",
"DecBtPwr/ IgnWlanAct", coex_dm->cur_dec_bt_pwr,
coex_dm->cur_ignore_wlan_act);
- CL_PRINTF(cli_buf);
/* Hw setting */
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s",
"============[Hw setting]============");
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x",
"RF-A, 0x1e initVal", coex_dm->bt_rf0x1e_backup);
- CL_PRINTF(cli_buf);
u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x778);
u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x880);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x",
"0x778/0x880[29:25]", u8tmp[0],
(u32tmp[0]&0x3e000000) >> 25);
- CL_PRINTF(cli_buf);
u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x948);
u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x67);
u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x765);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
"0x948/ 0x67[5] / 0x765",
u32tmp[0], ((u8tmp[0]&0x20) >> 5), u8tmp[1]);
- CL_PRINTF(cli_buf);
u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x92c);
u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x930);
u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x944);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
"0x92c[1:0]/ 0x930[7:0]/0x944[1:0]",
u32tmp[0]&0x3, u32tmp[1]&0xff, u32tmp[2]&0x3);
- CL_PRINTF(cli_buf);
u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x39);
u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x40);
u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x4c);
u8tmp[2] = btcoexist->btc_read_1byte(btcoexist, 0x64);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x",
"0x38[11]/0x40/0x4c[24:23]/0x64[0]",
((u8tmp[0] & 0x8)>>3), u8tmp[1],
((u32tmp[0]&0x01800000)>>23), u8tmp[2]&0x1);
- CL_PRINTF(cli_buf);
u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x550);
u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x522);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x",
"0x550(bcn ctrl)/0x522", u32tmp[0], u8tmp[0]);
- CL_PRINTF(cli_buf);
u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc50);
u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x49c);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x",
"0xc50(dig)/0x49c(null-drop)", u32tmp[0]&0xff, u8tmp[0]);
- CL_PRINTF(cli_buf);
u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xda0);
u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0xda4);
@@ -3397,29 +3366,25 @@ void ex_btc8723b2ant_display_coex_info(struct btc_coexist *btcoexist)
(u32tmp[3] & 0xffff);
fa_cck = (u8tmp[0] << 8) + u8tmp[1];
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
"OFDM-CCA/OFDM-FA/CCK-FA",
u32tmp[0]&0xffff, fa_ofdm, fa_cck);
- CL_PRINTF(cli_buf);
u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6c0);
u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x6c4);
u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x6c8);
u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x6cc);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x",
"0x6c0/0x6c4/0x6c8/0x6cc(coexTable)",
u32tmp[0], u32tmp[1], u32tmp[2], u8tmp[0]);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d",
"0x770(high-pri rx/tx)",
coex_sta->high_priority_rx, coex_sta->high_priority_tx);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d",
"0x774(low-pri rx/tx)", coex_sta->low_priority_rx,
coex_sta->low_priority_tx);
- CL_PRINTF(cli_buf);
#if (BT_AUTO_REPORT_ONLY_8723B_2ANT == 1)
btc8723b2ant_monitor_bt_ctr(btcoexist);
#endif
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a1ant.c b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a1ant.c
index 0b75e8c..b72e537 100644
--- a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a1ant.c
+++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a1ant.c
@@ -2235,7 +2235,7 @@ void ex_halbtc8821a1ant_display_coex_info(struct btc_coexist *btcoexist)
struct btc_board_info *board_info = &btcoexist->board_info;
struct btc_stack_info *stack_info = &btcoexist->stack_info;
struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
- u8 *cli_buf = btcoexist->cli_buf;
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
u8 u1_tmp[4], i, bt_info_ext, ps_tdma_case = 0;
u16 u2_tmp[4];
u32 u4_tmp[4];
@@ -2246,58 +2246,49 @@ void ex_halbtc8821a1ant_display_coex_info(struct btc_coexist *btcoexist)
u8 wifi_dot11_chnl, wifi_hs_chnl;
u32 fw_ver = 0, bt_patch_ver = 0;
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n ============[BT Coexist info]============");
- CL_PRINTF(cli_buf);
if (btcoexist->manual_control) {
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n ============[Under Manual Control]============");
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n ==========================================");
- CL_PRINTF(cli_buf);
}
if (btcoexist->stop_coex_dm) {
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n ============[Coex is STOPPED]============");
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n ==========================================");
- CL_PRINTF(cli_buf);
}
if (!board_info->bt_exist) {
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n BT not exists !!!");
- CL_PRINTF(cli_buf);
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n BT not exists !!!");
return;
}
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %d/ %d/ %d",
"Ant PG Num/ Ant Mech/ Ant Pos:",
board_info->pg_ant_num,
board_info->btdm_ant_num,
board_info->btdm_ant_pos);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %s / %d", "BT stack/ hci ext ver",
((stack_info->profile_notified) ? "Yes" : "No"),
stack_info->hci_version);
- CL_PRINTF(cli_buf);
btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER,
&bt_patch_ver);
btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %d_%x/ 0x%x/ 0x%x(%d)",
"CoexVer/ FwVer/ PatchVer",
glcoex_ver_date_8821a_1ant,
glcoex_ver_8821a_1ant,
fw_ver, bt_patch_ver,
bt_patch_ver);
- CL_PRINTF(cli_buf);
btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION,
&bt_hs_on);
@@ -2305,33 +2296,29 @@ void ex_halbtc8821a1ant_display_coex_info(struct btc_coexist *btcoexist)
&wifi_dot11_chnl);
btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_HS_CHNL,
&wifi_hs_chnl);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %d / %d(%d)",
"Dot11 channel / HsChnl(HsMode)",
wifi_dot11_chnl, wifi_hs_chnl, bt_hs_on);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %02x %02x %02x ",
"H2C Wifi inform bt chnl Info",
coex_dm->wifi_chnl_info[0], coex_dm->wifi_chnl_info[1],
coex_dm->wifi_chnl_info[2]);
- CL_PRINTF(cli_buf);
btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi);
btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %d/ %d", "Wifi rssi/ HS rssi",
(int)wifi_rssi, (int)bt_hs_rssi);
- CL_PRINTF(cli_buf);
btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan);
btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link);
btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %d/ %d/ %d ", "Wifi link/ roam/ scan",
link, roam, scan);
- CL_PRINTF(cli_buf);
btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G,
&wifi_under_5g);
@@ -2341,7 +2328,7 @@ void ex_halbtc8821a1ant_display_coex_info(struct btc_coexist *btcoexist)
&wifi_busy);
btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION,
&wifi_traffic_dir);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %s / %s/ %s ", "Wifi status",
(wifi_under_5g ? "5G" : "2.4G"),
((BTC_WIFI_BW_LEGACY == wifi_bw) ? "Legacy" :
@@ -2349,8 +2336,7 @@ void ex_halbtc8821a1ant_display_coex_info(struct btc_coexist *btcoexist)
((!wifi_busy) ? "idle" :
((BTC_WIFI_TRAFFIC_TX == wifi_traffic_dir) ?
"uplink" : "downlink")));
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = [%s/ %d/ %d] ", "BT [status/ rssi/ retryCnt]",
((btcoexist->bt_info.bt_disabled) ? ("disabled") :
((coex_sta->c2h_bt_inquiry_page) ? ("inquiry/page scan") :
@@ -2361,28 +2347,25 @@ void ex_halbtc8821a1ant_display_coex_info(struct btc_coexist *btcoexist)
coex_dm->bt_status) ?
"connected-idle" : "busy")))),
coex_sta->bt_rssi, coex_sta->bt_retry_cnt);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %d / %d / %d / %d", "SCO/HID/PAN/A2DP",
bt_link_info->sco_exist,
bt_link_info->hid_exist,
bt_link_info->pan_exist,
bt_link_info->a2dp_exist);
- CL_PRINTF(cli_buf);
btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_BT_LINK_INFO);
bt_info_ext = coex_sta->bt_info_ext;
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %s",
"BT Info A2DP rate",
(bt_info_ext&BIT0) ?
"Basic rate" : "EDR rate");
- CL_PRINTF(cli_buf);
for (i = 0; i < BT_INFO_SRC_8821A_1ANT_MAX; i++) {
if (coex_sta->bt_info_c2h_cnt[i]) {
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %02x %02x %02x %02x %02x %02x %02x(%d)",
glbt_info_src_8821a_1ant[i],
coex_sta->bt_info_c2h[i][0],
@@ -2393,49 +2376,42 @@ void ex_halbtc8821a1ant_display_coex_info(struct btc_coexist *btcoexist)
coex_sta->bt_info_c2h[i][5],
coex_sta->bt_info_c2h[i][6],
coex_sta->bt_info_c2h_cnt[i]);
- CL_PRINTF(cli_buf);
}
}
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %s/%s, (0x%x/0x%x)",
"PS state, IPS/LPS, (lps/rpwm)",
((coex_sta->under_ips ? "IPS ON" : "IPS OFF")),
((coex_sta->under_Lps ? "LPS ON" : "LPS OFF")),
btcoexist->bt_info.lps_val,
btcoexist->bt_info.rpwm_val);
- CL_PRINTF(cli_buf);
btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD);
if (!btcoexist->manual_control) {
/* Sw mechanism*/
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s", "============[Sw mechanism]============");
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %d", "SM[LowPenaltyRA]",
coex_dm->cur_low_penalty_ra);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %s/ %s/ %d ",
"DelBA/ BtCtrlAgg/ AggSize",
(btcoexist->bt_info.reject_agg_pkt ? "Yes" : "No"),
(btcoexist->bt_info.bt_ctrl_buf_size ? "Yes" : "No"),
btcoexist->bt_info.agg_buf_size);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = 0x%x ", "Rate Mask",
btcoexist->bt_info.ra_mask);
- CL_PRINTF(cli_buf);
/* Fw mechanism*/
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s",
"============[Fw mechanism]============");
- CL_PRINTF(cli_buf);
ps_tdma_case = coex_dm->cur_ps_tdma;
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %02x %02x %02x %02x %02x case-%d (auto:%d)",
"PS TDMA",
coex_dm->ps_tdma_para[0],
@@ -2445,115 +2421,99 @@ void ex_halbtc8821a1ant_display_coex_info(struct btc_coexist *btcoexist)
coex_dm->ps_tdma_para[4],
ps_tdma_case,
coex_dm->auto_tdma_adjust);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = 0x%x ",
"Latest error condition(should be 0)",
coex_dm->error_condition);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %d ", "IgnWlanAct",
coex_dm->cur_ignore_wlan_act);
- CL_PRINTF(cli_buf);
}
/* Hw setting*/
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s", "============[Hw setting]============");
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = 0x%x/0x%x/0x%x/0x%x",
"backup ARFR1/ARFR2/RL/AMaxTime",
coex_dm->backup_arfr_cnt1,
coex_dm->backup_arfr_cnt2,
coex_dm->backup_retry_limit,
coex_dm->backup_ampdu_max_time);
- CL_PRINTF(cli_buf);
u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x430);
u4_tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x434);
u2_tmp[0] = btcoexist->btc_read_2byte(btcoexist, 0x42a);
u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x456);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = 0x%x/0x%x/0x%x/0x%x",
"0x430/0x434/0x42a/0x456",
u4_tmp[0], u4_tmp[1], u2_tmp[0], u1_tmp[0]);
- CL_PRINTF(cli_buf);
u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x778);
u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc58);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = 0x%x/ 0x%x", "0x778/ 0xc58[29:25]",
u1_tmp[0], (u4_tmp[0]&0x3e000000) >> 25);
- CL_PRINTF(cli_buf);
u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x8db);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = 0x%x", "0x8db[6:5]",
((u1_tmp[0]&0x60)>>5));
- CL_PRINTF(cli_buf);
u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x975);
u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xcb4);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
"0xcb4[29:28]/0xcb4[7:0]/0x974[9:8]",
(u4_tmp[0] & 0x30000000)>>28,
u4_tmp[0] & 0xff,
u1_tmp[0] & 0x3);
- CL_PRINTF(cli_buf);
u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x40);
u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x4c);
u1_tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x64);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
"0x40/0x4c[24:23]/0x64[0]",
u1_tmp[0], ((u4_tmp[0]&0x01800000)>>23), u1_tmp[1]&0x1);
- CL_PRINTF(cli_buf);
u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x550);
u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x522);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = 0x%x/ 0x%x", "0x550(bcn ctrl)/0x522",
u4_tmp[0], u1_tmp[0]);
- CL_PRINTF(cli_buf);
u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc50);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = 0x%x", "0xc50(dig)",
u4_tmp[0]&0xff);
- CL_PRINTF(cli_buf);
u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xf48);
u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0xa5d);
u1_tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0xa5c);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = 0x%x/ 0x%x", "OFDM-FA/ CCK-FA",
u4_tmp[0], (u1_tmp[0]<<8) + u1_tmp[1]);
- CL_PRINTF(cli_buf);
u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6c0);
u4_tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x6c4);
u4_tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x6c8);
u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x6cc);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x",
"0x6c0/0x6c4/0x6c8/0x6cc(coexTable)",
u4_tmp[0], u4_tmp[1], u4_tmp[2], u1_tmp[0]);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %d/ %d", "0x770(high-pri rx/tx)",
coex_sta->high_priority_rx, coex_sta->high_priority_tx);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %d/ %d", "0x774(low-pri rx/tx)",
coex_sta->low_priority_rx, coex_sta->low_priority_tx);
- CL_PRINTF(cli_buf);
#if (BT_AUTO_REPORT_ONLY_8821A_1ANT == 1)
halbtc8821a1ant_monitor_bt_ctr(btcoexist);
#endif
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a2ant.c b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a2ant.c
index 2322b7d..cf819f0 100644
--- a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a2ant.c
+++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a2ant.c
@@ -3341,7 +3341,7 @@ ex_halbtc8821a2ant_display_coex_info(
{
struct btc_board_info *board_info = &btcoexist->board_info;
struct btc_stack_info *stack_info = &btcoexist->stack_info;
- u8 *cli_buf = btcoexist->cli_buf;
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
u8 u1tmp[4], i, bt_info_ext, ps_tdma_case = 0;
u32 u4tmp[4];
bool roam = false, scan = false, link = false, wifi_under_5g = false;
@@ -3351,41 +3351,35 @@ ex_halbtc8821a2ant_display_coex_info(
u8 wifi_dot_11_chnl, wifi_hs_chnl;
u32 fw_ver = 0, bt_patch_ver = 0;
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n ============[BT Coexist info]============");
- CL_PRINTF(cli_buf);
if (!board_info->bt_exist) {
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n BT not exists !!!");
- CL_PRINTF(cli_buf);
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n BT not exists !!!");
return;
}
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %d/ %d ", "Ant PG number/ Ant mechanism:",
board_info->pg_ant_num, board_info->btdm_ant_num);
- CL_PRINTF(cli_buf);
if (btcoexist->manual_control) {
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s", "[Action Manual control]!!");
- CL_PRINTF(cli_buf);
}
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %s / %d", "BT stack/ hci ext ver",
((stack_info->profile_notified) ? "Yes" : "No"),
stack_info->hci_version);
- CL_PRINTF(cli_buf);
btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER, &bt_patch_ver);
btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %d_%d/ 0x%x/ 0x%x(%d)",
"CoexVer/ FwVer/ PatchVer",
glcoex_ver_date_8821a_2ant, glcoex_ver_8821a_2ant,
fw_ver, bt_patch_ver, bt_patch_ver);
- CL_PRINTF(cli_buf);
btcoexist->btc_get(btcoexist,
BTC_GET_BL_HS_OPERATION, &bt_hs_on);
@@ -3393,33 +3387,29 @@ ex_halbtc8821a2ant_display_coex_info(
BTC_GET_U1_WIFI_DOT11_CHNL, &wifi_dot_11_chnl);
btcoexist->btc_get(btcoexist,
BTC_GET_U1_WIFI_HS_CHNL, &wifi_hs_chnl);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %d / %d(%d)",
"Dot11 channel / HsMode(HsChnl)",
wifi_dot_11_chnl, bt_hs_on, wifi_hs_chnl);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %02x %02x %02x ",
"H2C Wifi inform bt chnl Info",
coex_dm->wifi_chnl_info[0], coex_dm->wifi_chnl_info[1],
coex_dm->wifi_chnl_info[2]);
- CL_PRINTF(cli_buf);
btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi);
btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %ld/ %ld", "Wifi rssi/ HS rssi",
wifi_rssi, bt_hs_rssi);
- CL_PRINTF(cli_buf);
btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan);
btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link);
btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %d/ %d/ %d ", "Wifi link/ roam/ scan",
link, roam, scan);
- CL_PRINTF(cli_buf);
btcoexist->btc_get(btcoexist,
BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
@@ -3429,7 +3419,7 @@ ex_halbtc8821a2ant_display_coex_info(
BTC_GET_BL_WIFI_BUSY, &wifi_busy);
btcoexist->btc_get(btcoexist,
BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, &wifi_traffic_dir);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %s / %s/ %s ", "Wifi status",
(wifi_under_5g ? "5G" : "2.4G"),
((BTC_WIFI_BW_LEGACY == wifi_bw) ? "Legacy" :
@@ -3437,37 +3427,33 @@ ex_halbtc8821a2ant_display_coex_info(
((!wifi_busy) ? "idle" :
((BTC_WIFI_TRAFFIC_TX == wifi_traffic_dir) ?
"uplink" : "downlink")));
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = [%s/ %d/ %d] ", "BT [status/ rssi/ retryCnt]",
((coex_sta->c2h_bt_inquiry_page) ? ("inquiry/page scan") :
((BT_8821A_2ANT_BT_STATUS_IDLE == coex_dm->bt_status)
? "idle" : ((BT_8821A_2ANT_BT_STATUS_CON_IDLE ==
coex_dm->bt_status) ? "connected-idle" : "busy"))),
coex_sta->bt_rssi, coex_sta->bt_retry_cnt);
- CL_PRINTF(cli_buf);
if (stack_info->profile_notified) {
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %d / %d / %d / %d", "SCO/HID/PAN/A2DP",
stack_info->sco_exist, stack_info->hid_exist,
stack_info->pan_exist, stack_info->a2dp_exist);
- CL_PRINTF(cli_buf);
btcoexist->btc_disp_dbg_msg(btcoexist,
BTC_DBG_DISP_BT_LINK_INFO);
}
bt_info_ext = coex_sta->bt_info_ext;
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s",
"BT Info A2DP rate",
(bt_info_ext&BIT0) ? "Basic rate" : "EDR rate");
- CL_PRINTF(cli_buf);
for (i = 0; i < BT_INFO_SRC_8821A_2ANT_MAX; i++) {
if (coex_sta->bt_info_c2h_cnt[i]) {
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %02x %02x %02x %02x %02x %02x %02x(%d)",
glbt_info_src_8821a_2ant[i],
coex_sta->bt_info_c2h[i][0],
@@ -3478,139 +3464,118 @@ ex_halbtc8821a2ant_display_coex_info(
coex_sta->bt_info_c2h[i][5],
coex_sta->bt_info_c2h[i][6],
coex_sta->bt_info_c2h_cnt[i]);
- CL_PRINTF(cli_buf);
}
}
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/%s",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s/%s",
"PS state, IPS/LPS",
((coex_sta->under_ips ? "IPS ON" : "IPS OFF")),
((coex_sta->under_lps ? "LPS ON" : "LPS OFF")));
- CL_PRINTF(cli_buf);
btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD);
/* Sw mechanism*/
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s",
"============[Sw mechanism]============");
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %d/ %d/ %d/ %d ",
"SM1[ShRf/ LpRA/ LimDig/ btLna]",
coex_dm->cur_rf_rx_lpf_shrink, coex_dm->cur_low_penalty_ra,
coex_dm->limited_dig, coex_dm->cur_bt_lna_constrain);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %d/ %d/ %d(0x%x) ",
"SM2[AgcT/ AdcB/ SwDacSwing(lvl)]",
coex_dm->cur_agc_table_en, coex_dm->cur_adc_back_off,
coex_dm->cur_dac_swing_on, coex_dm->cur_dac_swing_lvl);
- CL_PRINTF(cli_buf);
/* Fw mechanism*/
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s",
"============[Fw mechanism]============");
- CL_PRINTF(cli_buf);
if (!btcoexist->manual_control) {
ps_tdma_case = coex_dm->cur_ps_tdma;
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %02x %02x %02x %02x %02x case-%d",
"PS TDMA",
coex_dm->ps_tdma_para[0], coex_dm->ps_tdma_para[1],
coex_dm->ps_tdma_para[2], coex_dm->ps_tdma_para[3],
coex_dm->ps_tdma_para[4], ps_tdma_case);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = %d/ %d ", "DecBtPwr/ IgnWlanAct",
coex_dm->cur_dec_bt_pwr,
coex_dm->cur_ignore_wlan_act);
- CL_PRINTF(cli_buf);
}
/* Hw setting*/
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s", "============[Hw setting]============");
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
"\r\n %-35s = 0x%x", "RF-A, 0x1e initVal",
coex_dm->bt_rf0x1e_backup);
- CL_PRINTF(cli_buf);
u1tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x778);
u1tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x6cc);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x ",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x ",
"0x778 (W_Act)/ 0x6cc (CoTab Sel)",
u1tmp[0], u1tmp[1]);
- CL_PRINTF(cli_buf);
u1tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x8db);
u1tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0xc5b);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x",
"0x8db(ADC)/0xc5b[29:25](DAC)",
((u1tmp[0]&0x60)>>5), ((u1tmp[1]&0x3e)>>1));
- CL_PRINTF(cli_buf);
u4tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xcb4);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x",
"0xcb4[7:0](ctrl)/ 0xcb4[29:28](val)",
u4tmp[0]&0xff, ((u4tmp[0]&0x30000000)>>28));
- CL_PRINTF(cli_buf);
u1tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x40);
u4tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x4c);
u4tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x974);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
"0x40/ 0x4c[24:23]/ 0x974",
u1tmp[0], ((u4tmp[0]&0x01800000)>>23), u4tmp[1]);
- CL_PRINTF(cli_buf);
u4tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x550);
u1tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x522);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x",
"0x550(bcn ctrl)/0x522",
u4tmp[0], u1tmp[0]);
- CL_PRINTF(cli_buf);
u4tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc50);
u1tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0xa0a);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x",
"0xc50(DIG)/0xa0a(CCK-TH)",
u4tmp[0], u1tmp[0]);
- CL_PRINTF(cli_buf);
u4tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xf48);
u1tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0xa5b);
u1tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0xa5c);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x",
"OFDM-FA/ CCK-FA",
u4tmp[0], (u1tmp[0]<<8) + u1tmp[1]);
- CL_PRINTF(cli_buf);
u4tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6c0);
u4tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x6c4);
u4tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x6c8);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
"0x6c0/0x6c4/0x6c8",
u4tmp[0], u4tmp[1], u4tmp[2]);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d",
"0x770 (hi-pri Rx/Tx)",
coex_sta->high_priority_rx, coex_sta->high_priority_tx);
- CL_PRINTF(cli_buf);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d",
"0x774(low-pri Rx/Tx)",
coex_sta->low_priority_rx, coex_sta->low_priority_tx);
- CL_PRINTF(cli_buf);
/* Tx mgnt queue hang or not, 0x41b should = 0xf, ex: 0xd ==>hang*/
u1tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x41b);
- CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x",
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x",
"0x41b (mgntQ hang chk == 0xf)",
u1tmp[0]);
- CL_PRINTF(cli_buf);
btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_COEX_STATISTICS);
}
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.c b/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.c
index 0620b22..fcf7459 100644
--- a/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.c
+++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.c
@@ -32,7 +32,6 @@
struct btc_coexist gl_bt_coexist;
u32 btc_dbg_type[BTC_MSG_MAX];
-static u8 btc_dbg_buf[100];
/***************************************************
* Debug related function
@@ -652,8 +651,6 @@ bool exhalbtc_initlize_variables(struct rtl_priv *adapter)
btcoexist->btc_get = halbtc_get;
btcoexist->btc_set = halbtc_set;
- btcoexist->cli_buf = &btc_dbg_buf[0];
-
btcoexist->bt_info.bt_ctrl_buf_size = false;
btcoexist->bt_info.agg_buf_size = 5;
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h b/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h
index bd03b8c..1345545 100644
--- a/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h
+++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h
@@ -116,9 +116,6 @@ extern u32 btc_dbg_type[];
#define WIFI_P2P_GO_CONNECTED BIT3
#define WIFI_P2P_GC_CONNECTED BIT4
-#define CL_SPRINTF snprintf
-#define CL_PRINTF(buf) printk("%s", buf)
-
#define BTC_PRINT(dbgtype, dbgflag, printstr, ...) \
do { \
if (unlikely(btc_dbg_type[dbgtype] & dbgflag)) {\
@@ -483,7 +480,6 @@ struct btc_coexist {
bool initilized;
bool stop_coex_dm;
bool manual_control;
- u8 *cli_buf;
struct btc_statistics statistics;
u8 pwr_mode_val[10];
--
1.8.4.5
^ permalink raw reply related
* Re: [PATCH net-next v2] net: filter: constify detection of pkt_type_offset
From: Daniel Borkmann @ 2014-09-12 20:48 UTC (permalink / raw)
To: Hannes Frederic Sowa
Cc: netdev, Eric Dumazet, Markos Chandras, Martin Schwidefsky,
Alexei Starovoitov, Denis Kirjanov
In-Reply-To: <3e68956a7e5b8bb9de226bfcc09092c6852a0a0a.1410523297.git.hannes@stressinduktion.org>
On 09/12/2014 02:04 PM, Hannes Frederic Sowa wrote:
> Currently we have 2 pkt_type_offset functions doing the same thing and
> spread across the architecture files. Remove those and replace them
> with a PKT_TYPE_OFFSET macro helper which gets the constant value from a
> zero sized sk_buff member right in front of the bitfield with offsetof.
> This new offset marker does not change size of struct sk_buff.
>
> Cc: Eric Dumazet <eric.dumazet@gmail.com>
> Cc: Markos Chandras <markos.chandras@imgtec.com>
> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
> Cc: Daniel Borkmann <dborkman@redhat.com>
> Cc: Alexei Starovoitov <alexei.starovoitov@gmail.com>
> Signed-off-by: Denis Kirjanov <kda@linux-powerpc.org>
> Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Looks good to me, thanks!
Acked-by: Daniel Borkmann <dborkman@redhat.com>
^ permalink raw reply
* [PATCH 2/3] bridge: Add filtering support for default_pvid
From: Vladislav Yasevich @ 2014-09-12 20:44 UTC (permalink / raw)
To: netdev; +Cc: shemminger, bridge, Toshiaki Makita, Vladislav Yasevich
In-Reply-To: <1410554691-18467-1-git-send-email-vyasevic@redhat.com>
Currently when vlan filtering is turned on on the bridge, the bridge
will drop all traffic untill the user configures the filter. This
isn't very nice for ports that don't care about vlans and just
want untagged traffic.
A concept of a default_pvid was recently introduced. This patch
adds filtering support for default_pvid. Now, ports that don't
care about vlans and don't define there own filter will belong
to the VLAN of the default_pvid and continue to receive untagged
traffic.
Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
---
net/bridge/br_device.c | 8 +++--
net/bridge/br_if.c | 2 ++
net/bridge/br_private.h | 13 ++++++--
net/bridge/br_vlan.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++--
4 files changed, 104 insertions(+), 6 deletions(-)
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index 568cccd..af8f706 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -88,12 +88,17 @@ out:
static int br_dev_init(struct net_device *dev)
{
struct net_bridge *br = netdev_priv(dev);
+ int err;
br->stats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
if (!br->stats)
return -ENOMEM;
- return 0;
+ err = br_vlan_init(br);
+ if (err)
+ free_percpu(br->stats);
+
+ return err;
}
static int br_dev_open(struct net_device *dev)
@@ -389,5 +394,4 @@ void br_dev_setup(struct net_device *dev)
br_netfilter_rtable_init(br);
br_stp_timer_init(br);
br_multicast_init(br);
- br_vlan_init(br);
}
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index a9f54a9..cb2b20f 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -500,6 +500,8 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
if (br_fdb_insert(br, p, dev->dev_addr, 0))
netdev_err(dev, "failed insert local address bridge forwarding table\n");
+ nbp_vlan_init(p);
+
spin_lock_bh(&br->lock);
changed_addr = br_stp_recalculate_bridge_id(br);
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 84c9a5d..bb4abdf 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -602,12 +602,13 @@ bool br_vlan_find(struct net_bridge *br, u16 vid);
void br_recalculate_fwd_mask(struct net_bridge *br);
int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val);
int br_vlan_set_proto(struct net_bridge *br, unsigned long val);
-void br_vlan_init(struct net_bridge *br);
+int br_vlan_init(struct net_bridge *br);
int br_vlan_set_default_pvid(struct net_bridge *br, unsigned long val);
int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags);
int nbp_vlan_delete(struct net_bridge_port *port, u16 vid);
void nbp_vlan_flush(struct net_bridge_port *port);
bool nbp_vlan_find(struct net_bridge_port *port, u16 vid);
+int nbp_vlan_init(struct net_bridge_port *port);
static inline struct net_port_vlans *br_get_vlan_info(
const struct net_bridge *br)
@@ -640,6 +641,8 @@ static inline int br_vlan_get_tag(const struct sk_buff *skb, u16 *vid)
static inline u16 br_get_pvid(const struct net_port_vlans *v)
{
+ if (!v)
+ return VLAN_N_VID;
/* Return just the VID if it is set, or VLAN_N_VID (invalid vid) if
* vid wasn't set
*/
@@ -703,8 +706,9 @@ static inline void br_recalculate_fwd_mask(struct net_bridge *br)
{
}
-static inline void br_vlan_init(struct net_bridge *br)
+static inline int br_vlan_init(struct net_bridge *br)
{
+ return 0;
}
static inline int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags)
@@ -737,6 +741,11 @@ static inline bool nbp_vlan_find(struct net_bridge_port *port, u16 vid)
return false;
}
+static inline int nbp_vlan_init(struct net_bridge_port *port)
+{
+ return 0;
+}
+
static inline u16 br_vlan_get_tag(const struct sk_buff *skb, u16 *tag)
{
return 0;
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
index 43a297b..4b807ef 100644
--- a/net/bridge/br_vlan.c
+++ b/net/bridge/br_vlan.c
@@ -489,6 +489,80 @@ err_filt:
goto unlock;
}
+static int __br_vlan_set_default_pvid(struct net_bridge *br, u16 pvid)
+{
+ struct net_bridge_port *p;
+ u16 old_pvid;
+ int err;
+ DECLARE_BITMAP(changed, BR_MAX_PORTS);
+
+ bitmap_zero(changed, BR_MAX_PORTS);
+
+ /* This function runs with filtering turned off so we can
+ * remove the old pvid configuration and add the new one after
+ * without impacting traffic.
+ */
+
+ old_pvid = br->default_pvid;
+
+ /* If the user has set a different PVID or if the new default pvid
+ * conflicts with user configuration, do not modify the configuration.
+ */
+ if (old_pvid != br_get_pvid(br_get_vlan_info(br)) ||
+ br_vlan_find(br, pvid))
+ goto do_ports;
+
+ set_bit(0, changed);
+ br_vlan_delete(br, old_pvid);
+ err = br_vlan_add(br, pvid,
+ BRIDGE_VLAN_INFO_PVID | BRIDGE_VLAN_INFO_UNTAGGED);
+ if (err)
+ goto err_br;
+
+do_ports:
+ list_for_each_entry(p, &br->port_list, list) {
+ /* If the user has set a different PVID or if the new default
+ * pvid conflicts with user configuration, do not modify the
+ * configuration.
+ */
+ if (old_pvid != br_get_pvid(nbp_get_vlan_info(p)) ||
+ nbp_vlan_find(p, pvid))
+ continue;
+
+ set_bit(p->port_no, changed);
+ err = nbp_vlan_add(p, pvid,
+ BRIDGE_VLAN_INFO_PVID |
+ BRIDGE_VLAN_INFO_UNTAGGED);
+ if (err)
+ goto err_port;
+ nbp_vlan_delete(p, old_pvid);
+ }
+
+ br->default_pvid = pvid;
+
+ return 0;
+
+err_port:
+ list_for_each_entry_continue_reverse(p, &br->port_list, list) {
+ if (!test_bit(p->port_no, changed))
+ continue;
+
+ nbp_vlan_delete(p, pvid);
+ nbp_vlan_add(p, old_pvid,
+ BRIDGE_VLAN_INFO_PVID |
+ BRIDGE_VLAN_INFO_UNTAGGED);
+ }
+
+err_br:
+ if (test_bit(0, changed)) {
+ br_vlan_delete(br, pvid);
+ br_vlan_add(br, old_pvid,
+ BRIDGE_VLAN_INFO_PVID |
+ BRIDGE_VLAN_INFO_UNTAGGED);
+ }
+ return err;
+}
+
int br_vlan_set_default_pvid(struct net_bridge *br, unsigned long val)
{
u16 pvid = val;
@@ -509,17 +583,19 @@ int br_vlan_set_default_pvid(struct net_bridge *br, unsigned long val)
goto unlock;
}
- br->default_pvid = vid;
+ err = __br_vlan_set_default_pvid(br, pvid);
unlock:
rtnl_unlock();
return err;
}
-void br_vlan_init(struct net_bridge *br)
+int br_vlan_init(struct net_bridge *br)
{
br->vlan_proto = htons(ETH_P_8021Q);
br->default_pvid = 1;
+ return br_vlan_add(br, 1,
+ BRIDGE_VLAN_INFO_PVID | BRIDGE_VLAN_INFO_UNTAGGED);
}
/* Must be protected by RTNL.
@@ -611,3 +687,10 @@ out:
rcu_read_unlock();
return found;
}
+
+int nbp_vlan_init(struct net_bridge_port *p)
+{
+ return nbp_vlan_add(p, p->br->default_pvid,
+ BRIDGE_VLAN_INFO_PVID |
+ BRIDGE_VLAN_INFO_UNTAGGED);
+}
--
1.9.3
^ permalink raw reply related
* [PATCH 3/3] bridge; Automatically filter vlans configured on top of bridge
From: Vladislav Yasevich @ 2014-09-12 20:44 UTC (permalink / raw)
To: netdev; +Cc: shemminger, bridge, Toshiaki Makita, Vladislav Yasevich
In-Reply-To: <1410554691-18467-1-git-send-email-vyasevic@redhat.com>
If the user configures vlan devices on top of the bridge,
automatically set up filter entries for it as long as
bridge vlan protocol matches that of the vlan.
This allows the user to atomatically receive vlan traffic
for the vlans that are convifgured.
Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
---
net/bridge/br_device.c | 46 +++++++++++++++++++++++++++++++++++++++++++---
net/bridge/br_private.h | 20 ++++++++++++++++++++
2 files changed, 63 insertions(+), 3 deletions(-)
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index af8f706..1e8caec 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -307,6 +307,45 @@ static int br_del_slave(struct net_device *dev, struct net_device *slave_dev)
return br_del_if(br, slave_dev);
}
+static int br_vlan_rx_add_vid(struct net_device *br_dev,
+ __be16 proto, u16 vid)
+{
+ struct net_bridge *br = netdev_priv(br_dev);
+
+ if (proto != br_vlan_protocol(br))
+ return 0;
+
+ /* vid 0 is special and will be added by the vlan layer to lower
+ * devices. Don't do anything here.
+ */
+ if (vid == 0)
+ return 0;
+
+ return br_vlan_add(br, vid, 0);
+}
+
+static int br_vlan_rx_kill_vid(struct net_device *br_dev,
+ __be16 proto, u16 vid)
+{
+ struct net_bridge *br = netdev_priv(br_dev);
+
+ if (proto != br_vlan_protocol(br))
+ return 0;
+
+ /* vid 0 is special and will be removed by the vlan layer from lower
+ * devices. Don't do anything here.
+ */
+ if (vid == 0)
+ return 0;
+
+ /* Don't report error. This will fail if the vlan was
+ * previousely remove by some other means and we don't
+ * wan't to polute the log/bug the user.
+ */
+ br_vlan_delete(br, vid);
+ return 0;
+}
+
static const struct ethtool_ops br_ethtool_ops = {
.get_drvinfo = br_getinfo,
.get_link = ethtool_op_get_link,
@@ -337,6 +376,8 @@ static const struct net_device_ops br_netdev_ops = {
.ndo_bridge_getlink = br_getlink,
.ndo_bridge_setlink = br_setlink,
.ndo_bridge_dellink = br_dellink,
+ .ndo_vlan_rx_add_vid = br_vlan_rx_add_vid,
+ .ndo_vlan_rx_kill_vid = br_vlan_rx_kill_vid,
};
static void br_dev_free(struct net_device *dev)
@@ -366,9 +407,8 @@ void br_dev_setup(struct net_device *dev)
dev->priv_flags = IFF_EBRIDGE;
dev->features = COMMON_FEATURES | NETIF_F_LLTX | NETIF_F_NETNS_LOCAL |
- NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX;
- dev->hw_features = COMMON_FEATURES | NETIF_F_HW_VLAN_CTAG_TX |
- NETIF_F_HW_VLAN_STAG_TX;
+ BRIDGE_VLAN_FEATURES;
+ dev->hw_features = COMMON_FEATURES | BRIDGE_VLAN_FEATURES;
dev->vlan_features = COMMON_FEATURES;
br->dev = dev;
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index bb4abdf..73a1563 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -29,6 +29,16 @@
#define BR_MAX_PORTS (1<<BR_PORT_BITS)
#define BR_VLAN_BITMAP_LEN BITS_TO_LONGS(VLAN_N_VID)
+#ifdef CONFIG_BRIDGE_VLAN_FILTERING
+#define BRIDGE_VLAN_FEATURES (NETIF_F_HW_VLAN_CTAG_TX | \
+ NETIF_F_HW_VLAN_CTAG_FILTER | \
+ NETIF_F_HW_VLAN_STAG_TX | \
+ NETIF_F_HW_VLAN_STAG_FILTER)
+#else
+#define BRIDGE_VLAN_FEATURES (NETIF_F_HW_VLAN_CTAG_TX | \
+ NETIF_F_HW_VLAN_STAG_TX)
+#endif
+
#define BR_VERSION "2.3"
/* Control of forwarding link local multicast */
@@ -654,6 +664,11 @@ static inline int br_vlan_enabled(struct net_bridge *br)
{
return br->vlan_enabled;
}
+
+static inline __be16 br_vlan_protocol(struct net_bridge *br)
+{
+ return br->vlan_proto;
+}
#else
static inline bool br_allowed_ingress(struct net_bridge *br,
struct net_port_vlans *v,
@@ -759,6 +774,11 @@ static inline int br_vlan_enabled(struct net_bridge *br)
{
return 0;
}
+
+static inline __be16 br_vlan_protocol(struct net_bridge *br)
+{
+ return 0;
+}
#endif
/* br_netfilter.c */
--
1.9.3
^ permalink raw reply related
* Re: [Patch v3 net-next 09/12] net: fec: change FEC alignment according to i.mx6 sx requirement
From: Zhi Li @ 2014-09-12 20:45 UTC (permalink / raw)
To: David Miller
Cc: Frank.Li@freescale.com, Duan Fugang-B38611,
netdev@vger.kernel.org, Shawn Guo,
linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org,
Russell King - ARM Linux
In-Reply-To: <20140912.164047.810313458974612565.davem@davemloft.net>
On Fri, Sep 12, 2014 at 3:40 PM, David Miller <davem@davemloft.net> wrote:
> From: Frank Li <Frank.Li@freescale.com>
> Date: Thu, 11 Sep 2014 02:30:42 +0800
>
>> +
>> + unsigned tx_align;
>> + unsigned rx_align;
>> };
>
> Please always fully write out "unsigned int" rather than just "unsigned".
>
>> @@ -2399,6 +2393,7 @@ fec_enet_alloc_rxq_buffers(struct net_device *ndev, unsigned int queue)
>> struct sk_buff *skb;
>> struct bufdesc *bdp;
>> struct fec_enet_priv_rx_q *rxq;
>> + unsigned off;
>
> Likewise.
Okay, I will fix it next version.
best regards
Frank Li
^ permalink raw reply
* [PATCH 1/3] bridge: Add a default_pvid sysfs attribute
From: Vladislav Yasevich @ 2014-09-12 20:44 UTC (permalink / raw)
To: netdev; +Cc: shemminger, bridge, Toshiaki Makita, Vladislav Yasevich
In-Reply-To: <1410554691-18467-1-git-send-email-vyasevic@redhat.com>
This patch allows the user to set and retrieve default_pvid
value. A new value can only be stored when vlan filtering
is disabled.
Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
---
net/bridge/br_private.h | 2 ++
net/bridge/br_sysfs_br.c | 17 +++++++++++++++++
net/bridge/br_vlan.c | 28 ++++++++++++++++++++++++++++
3 files changed, 47 insertions(+)
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 62a7fa2..84c9a5d 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -299,6 +299,7 @@ struct net_bridge
#ifdef CONFIG_BRIDGE_VLAN_FILTERING
u8 vlan_enabled;
__be16 vlan_proto;
+ u16 default_pvid;
struct net_port_vlans __rcu *vlan_info;
#endif
};
@@ -602,6 +603,7 @@ void br_recalculate_fwd_mask(struct net_bridge *br);
int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val);
int br_vlan_set_proto(struct net_bridge *br, unsigned long val);
void br_vlan_init(struct net_bridge *br);
+int br_vlan_set_default_pvid(struct net_bridge *br, unsigned long val);
int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags);
int nbp_vlan_delete(struct net_bridge_port *port, u16 vid);
void nbp_vlan_flush(struct net_bridge_port *port);
diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c
index c9e2572..b969d9e 100644
--- a/net/bridge/br_sysfs_br.c
+++ b/net/bridge/br_sysfs_br.c
@@ -725,6 +725,22 @@ static ssize_t vlan_protocol_store(struct device *d,
return store_bridge_parm(d, buf, len, br_vlan_set_proto);
}
static DEVICE_ATTR_RW(vlan_protocol);
+
+static ssize_t default_pvid_show(struct device *d,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct net_bridge *br = to_bridge(d);
+ return sprintf(buf, "%d\n", br->default_pvid);
+}
+
+static ssize_t default_pvid_store(struct device *d,
+ struct device_attribute *attr,
+ const char *buf, size_t len)
+{
+ return store_bridge_parm(d, buf, len, br_vlan_set_default_pvid);
+}
+static DEVICE_ATTR_RW(default_pvid);
#endif
static struct attribute *bridge_attrs[] = {
@@ -771,6 +787,7 @@ static struct attribute *bridge_attrs[] = {
#ifdef CONFIG_BRIDGE_VLAN_FILTERING
&dev_attr_vlan_filtering.attr,
&dev_attr_vlan_protocol.attr,
+ &dev_attr_default_pvid.attr,
#endif
NULL
};
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
index e1bcd65..43a297b 100644
--- a/net/bridge/br_vlan.c
+++ b/net/bridge/br_vlan.c
@@ -489,9 +489,37 @@ err_filt:
goto unlock;
}
+int br_vlan_set_default_pvid(struct net_bridge *br, unsigned long val)
+{
+ u16 pvid = val;
+ int err = 0;
+
+ if (!pvid || pvid >= VLAN_VID_MASK)
+ return -EINVAL;
+
+ if (!rtnl_trylock())
+ return restart_syscall();
+
+ if (pvid == br->default_pvid)
+ goto unlock;
+
+ /* Only allow default pvid change when filtering is disabled */
+ if (br->vlan_enabled) {
+ err = -EPERM;
+ goto unlock;
+ }
+
+ br->default_pvid = vid;
+
+unlock:
+ rtnl_unlock();
+ return err;
+}
+
void br_vlan_init(struct net_bridge *br)
{
br->vlan_proto = htons(ETH_P_8021Q);
+ br->default_pvid = 1;
}
/* Must be protected by RTNL.
--
1.9.3
^ permalink raw reply related
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