Date   

Re: [PATCH 4.19.y-cip 5/6] Backport netfilter: nf_tables: autoload modules from the abort path

Fong, Amy
 

From e6cec303e31d347aa44beb37876fa6763cc0430c Mon Sep 17 00:00:00 2001
From: Pablo Neira Ayuso <pablo@...>
Date: Thu, 29 Oct 2020 13:50:03 +0100
Subject: [PATCH 5/5] netfilter: nf_tables: missing validation from the abort
path

If userspace does not include the trailing end of batch message, then
nfnetlink aborts the transaction. This allows to check that ruleset
updates trigger no errors.

After this patch, invoking this command from the prerouting chain:

# nft -c add rule x y fib saddr . oif type local

fails since oif is not supported there.

This patch fixes the lack of rule validation from the abort/check path
to catch configuration errors such as the one above.

Fixes: a654de8fdc18 ("netfilter: nf_tables: fix chain dependency validation")
Signed-off-by: Pablo Neira Ayuso <pablo@...>
(cherry picked from commit c0391b6ab810381df632677a1dcbbbbd63d05b6d)
---
include/linux/netfilter/nfnetlink.h | 9 ++++++++-
net/netfilter/nf_tables_api.c | 15 ++++++++++-----
net/netfilter/nfnetlink.c | 22 ++++++++++++++++++----
3 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h
index 89016d08f6a2..f6267e2883f2 100644
--- a/include/linux/netfilter/nfnetlink.h
+++ b/include/linux/netfilter/nfnetlink.h
@@ -24,6 +24,12 @@ struct nfnl_callback {
const u_int16_t attr_count; /* number of nlattr's */
};

+enum nfnl_abort_action {
+ NFNL_ABORT_NONE = 0,
+ NFNL_ABORT_AUTOLOAD,
+ NFNL_ABORT_VALIDATE,
+};
+
struct nfnetlink_subsystem {
const char *name;
__u8 subsys_id; /* nfnetlink subsystem ID */
@@ -31,7 +37,8 @@ struct nfnetlink_subsystem {
const struct nfnl_callback *cb; /* callback for individual types */
struct module *owner;
int (*commit)(struct net *net, struct sk_buff *skb);
- int (*abort)(struct net *net, struct sk_buff *skb, bool autoload);
+ int (*abort)(struct net *net, struct sk_buff *skb,
+ enum nfnl_abort_action action);
void (*cleanup)(struct net *net);
bool (*valid_genid)(struct net *net, u32 genid);
};
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 54bf2ac44531..e15e574f035d 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -6734,11 +6734,15 @@ static void nf_tables_abort_release(struct nft_trans *trans)
kfree(trans);
}

-static int __nf_tables_abort(struct net *net, bool autoload)
+static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action)
{
struct nft_trans *trans, *next;
struct nft_trans_elem *te;

+ if (action == NFNL_ABORT_VALIDATE &&
+ nf_tables_validate(net) < 0)
+ return -EAGAIN;
+
list_for_each_entry_safe_reverse(trans, next, &net->nft.commit_list,
list) {
switch (trans->msg_type) {
@@ -6851,7 +6855,7 @@ static int __nf_tables_abort(struct net *net, bool autoload)
nf_tables_abort_release(trans);
}

- if (autoload)
+ if (action == NFNL_ABORT_AUTOLOAD)
nf_tables_module_autoload(net);
else
nf_tables_module_autoload_cleanup(net);
@@ -6864,9 +6868,10 @@ static void nf_tables_cleanup(struct net *net)
nft_validate_state_update(net, NFT_VALIDATE_SKIP);
}

-static int nf_tables_abort(struct net *net, struct sk_buff *skb, bool autoload)
+static int nf_tables_abort(struct net *net, struct sk_buff *skb,
+ enum nfnl_abort_action action)
{
- int ret = __nf_tables_abort(net, autoload);
+ int ret = __nf_tables_abort(net, action);

mutex_unlock(&net->nft.commit_mutex);

@@ -7472,7 +7477,7 @@ static void __net_exit nf_tables_exit_net(struct net *net)
{
mutex_lock(&net->nft.commit_mutex);
if (!list_empty(&net->nft.commit_list))
- __nf_tables_abort(net, false);
+ __nf_tables_abort(net, NFNL_ABORT_NONE);
__nft_release_tables(net);
mutex_unlock(&net->nft.commit_mutex);
WARN_ON_ONCE(!list_empty(&net->nft.tables));
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index 7454f135e19d..4f5dcdf1a39e 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -314,7 +314,7 @@ static void nfnetlink_rcv_batch(struct sk_buff *skb, struct nlmsghdr *nlh,
return netlink_ack(skb, nlh, -EINVAL, NULL);
replay:
status = 0;
-
+replay_abort:
skb = netlink_skb_clone(oskb, GFP_KERNEL);
if (!skb)
return netlink_ack(oskb, nlh, -ENOMEM, NULL);
@@ -478,7 +478,7 @@ static void nfnetlink_rcv_batch(struct sk_buff *skb, struct nlmsghdr *nlh,
}
done:
if (status & NFNL_BATCH_REPLAY) {
- ss->abort(net, oskb, true);
+ ss->abort(net, oskb, NFNL_ABORT_AUTOLOAD);
nfnl_err_reset(&err_list);
kfree_skb(skb);
module_put(ss->owner);
@@ -489,11 +489,25 @@ static void nfnetlink_rcv_batch(struct sk_buff *skb, struct nlmsghdr *nlh,
status |= NFNL_BATCH_REPLAY;
goto done;
} else if (err) {
- ss->abort(net, oskb, false);
+ ss->abort(net, oskb, NFNL_ABORT_NONE);
netlink_ack(oskb, nlmsg_hdr(oskb), err, NULL);
}
} else {
- ss->abort(net, oskb, false);
+ enum nfnl_abort_action abort_action;
+
+ if (status & NFNL_BATCH_FAILURE)
+ abort_action = NFNL_ABORT_NONE;
+ else
+ abort_action = NFNL_ABORT_VALIDATE;
+
+ err = ss->abort(net, oskb, abort_action);
+ if (err == -EAGAIN) {
+ nfnl_err_reset(&err_list);
+ kfree_skb(skb);
+ module_put(ss->owner);
+ status |= NFNL_BATCH_FAILURE;
+ goto replay_abort;
+ }
}
if (ss->cleanup)
ss->cleanup(net);
--
2.34.1


Re: [PATCH 4.19.y-cip 4/6] Backport netfilter: nf_tables: autoload modules from the abort path

Fong, Amy
 

From 791580bd2a8b75daddc0d110582198ab0ac854b2 Mon Sep 17 00:00:00 2001
From: Florian Westphal <fw@...>
Date: Thu, 5 Mar 2020 11:15:36 +0100
Subject: [PATCH 4/5] netfilter: nf_tables: fix infinite loop when expr is not
available

nft will loop forever if the kernel doesn't support an expression:

1. nft_expr_type_get() appends the family specific name to the module list.
2. -EAGAIN is returned to nfnetlink, nfnetlink calls abort path.
3. abort path sets ->done to true and calls request_module for the
expression.
4. nfnetlink replays the batch, we end up in nft_expr_type_get() again.
5. nft_expr_type_get attempts to append family-specific name. This
one already exists on the list, so we continue
6. nft_expr_type_get adds the generic expression name to the module
list. -EAGAIN is returned, nfnetlink calls abort path.
7. abort path encounters the family-specific expression which
has 'done' set, so it gets removed.
8. abort path requests the generic expression name, sets done to true.
9. batch is replayed.

If the expression could not be loaded, then we will end up back at 1),
because the family-specific name got removed and the cycle starts again.

Note that userspace can SIGKILL the nft process to stop the cycle, but
the desired behaviour is to return an error after the generic expr name
fails to load the expression.

Fixes: eb014de4fd418 ("netfilter: nf_tables: autoload modules from the abort path")
Signed-off-by: Florian Westphal <fw@...>
Signed-off-by: Pablo Neira Ayuso <pablo@...>
(cherry picked from commit 1d305ba40eb8081ff21eeb8ca6ba5c70fd920934)
---
net/netfilter/nf_tables_api.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 6329d23c8b35..54bf2ac44531 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -6698,13 +6698,8 @@ static void nf_tables_module_autoload(struct net *net)
list_splice_init(&net->nft.module_list, &module_list);
mutex_unlock(&net->nft.commit_mutex);
list_for_each_entry_safe(req, next, &module_list, list) {
- if (req->done) {
- list_del(&req->list);
- kfree(req);
- } else {
- request_module("%s", req->module);
- req->done = true;
- }
+ request_module("%s", req->module);
+ req->done = true;
}
mutex_lock(&net->nft.commit_mutex);
list_splice(&module_list, &net->nft.module_list);
@@ -7481,6 +7476,7 @@ static void __net_exit nf_tables_exit_net(struct net *net)
__nft_release_tables(net);
mutex_unlock(&net->nft.commit_mutex);
WARN_ON_ONCE(!list_empty(&net->nft.tables));
+ WARN_ON_ONCE(!list_empty(&net->nft.module_list));
}

static struct pernet_operations nf_tables_net_ops = {
--
2.34.1


Re: [PATCH 4.19.y-cip 3/6] Backport netfilter: nf_tables: autoload modules from the abort path

Fong, Amy
 

From 5a9ec0a60c682805ceb0cca413d355f75c74b9ba Mon Sep 17 00:00:00 2001
From: Pablo Neira Ayuso <pablo@...>
Date: Tue, 21 Jan 2020 16:48:03 +0100
Subject: [PATCH 3/5] netfilter: nf_tables: autoload modules from the abort
path

This patch introduces a list of pending module requests. This new module
list is composed of nft_module_request objects that contain the module
name and one status field that tells if the module has been already
loaded (the 'done' field).

In the first pass, from the preparation phase, the netlink command finds
that a module is missing on this list. Then, a module request is
allocated and added to this list and nft_request_module() returns
-EAGAIN. This triggers the abort path with the autoload parameter set on
from nfnetlink, request_module() is called and the module request enters
the 'done' state. Since the mutex is released when loading modules from
the abort phase, the module list is zapped so this is iteration occurs
over a local list. Therefore, the request_module() calls happen when
object lists are in consistent state (after fulling aborting the
transaction) and the commit list is empty.

On the second pass, the netlink command will find that it already tried
to load the module, so it does not request it again and
nft_request_module() returns 0. Then, there is a look up to find the
object that the command was missing. If the module was successfully
loaded, the command proceeds normally since it finds the missing object
in place, otherwise -ENOENT is reported to userspace.

This patch also updates nfnetlink to include the reason to enter the
abort phase, which is required for this new autoload module rationale.

Fixes: ec7470b834fe ("netfilter: nf_tables: store transaction list locally while requesting module")
Reported-by: syzbot+29125d208b3dae9a7019@...
Signed-off-by: Pablo Neira Ayuso <pablo@...>
(cherry picked from commit eb014de4fd418de1a277913cba244e47274fe392)
---
include/linux/netfilter/nfnetlink.h | 2 +-
include/net/netns/nftables.h | 1 +
net/netfilter/nf_tables_api.c | 126 ++++++++++++++++++++--------
net/netfilter/nfnetlink.c | 6 +-
4 files changed, 94 insertions(+), 41 deletions(-)

diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h
index e713476ff29d..89016d08f6a2 100644
--- a/include/linux/netfilter/nfnetlink.h
+++ b/include/linux/netfilter/nfnetlink.h
@@ -31,7 +31,7 @@ struct nfnetlink_subsystem {
const struct nfnl_callback *cb; /* callback for individual types */
struct module *owner;
int (*commit)(struct net *net, struct sk_buff *skb);
- int (*abort)(struct net *net, struct sk_buff *skb);
+ int (*abort)(struct net *net, struct sk_buff *skb, bool autoload);
void (*cleanup)(struct net *net);
bool (*valid_genid)(struct net *net, u32 genid);
};
diff --git a/include/net/netns/nftables.h b/include/net/netns/nftables.h
index 286fd960896f..a1a8d45adb42 100644
--- a/include/net/netns/nftables.h
+++ b/include/net/netns/nftables.h
@@ -7,6 +7,7 @@
struct netns_nftables {
struct list_head tables;
struct list_head commit_list;
+ struct list_head module_list;
struct mutex commit_mutex;
unsigned int base_seq;
u8 gencursor;
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 8ec38de1f7a1..6329d23c8b35 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -501,35 +501,45 @@ __nf_tables_chain_type_lookup(const struct nlattr *nla, u8 family)
return NULL;
}

-/*
- * Loading a module requires dropping mutex that guards the transaction.
- * A different client might race to start a new transaction meanwhile. Zap the
- * list of pending transaction and then restore it once the mutex is grabbed
- * again. Users of this function return EAGAIN which implicitly triggers the
- * transaction abort path to clean up the list of pending transactions.
- */
+struct nft_module_request {
+ struct list_head list;
+ char module[MODULE_NAME_LEN];
+ bool done;
+};
+
#ifdef CONFIG_MODULES
-static void nft_request_module(struct net *net, const char *fmt, ...)
+static int nft_request_module(struct net *net, const char *fmt, ...)
{
char module_name[MODULE_NAME_LEN];
- LIST_HEAD(commit_list);
+ struct nft_module_request *req;
va_list args;
int ret;

- list_splice_init(&net->nft.commit_list, &commit_list);
-
va_start(args, fmt);
ret = vsnprintf(module_name, MODULE_NAME_LEN, fmt, args);
va_end(args);
if (ret >= MODULE_NAME_LEN)
- return;
+ return 0;

- mutex_unlock(&net->nft.commit_mutex);
- request_module("%s", module_name);
- mutex_lock(&net->nft.commit_mutex);
+ list_for_each_entry(req, &net->nft.module_list, list) {
+ if (!strcmp(req->module, module_name)) {
+ if (req->done)
+ return 0;

- WARN_ON_ONCE(!list_empty(&net->nft.commit_list));
- list_splice(&commit_list, &net->nft.commit_list);
+ /* A request to load this module already exists. */
+ return -EAGAIN;
+ }
+ }
+
+ req = kmalloc(sizeof(*req), GFP_KERNEL);
+ if (!req)
+ return -ENOMEM;
+
+ req->done = false;
+ strlcpy(req->module, module_name, MODULE_NAME_LEN);
+ list_add_tail(&req->list, &net->nft.module_list);
+
+ return -EAGAIN;
}
#endif

@@ -554,10 +564,9 @@ nf_tables_chain_type_lookup(struct net *net, const struct nlattr *nla,
lockdep_nfnl_nft_mutex_not_held();
#ifdef CONFIG_MODULES
if (autoload) {
- nft_request_module(net, "nft-chain-%u-%.*s", family,
- nla_len(nla), (const char *)nla_data(nla));
- type = __nf_tables_chain_type_lookup(nla, family);
- if (type != NULL)
+ if (nft_request_module(net, "nft-chain-%u-%.*s", family,
+ nla_len(nla),
+ (const char *)nla_data(nla)) == -EAGAIN)
return ERR_PTR(-EAGAIN);
}
#endif
@@ -2013,9 +2022,8 @@ static const struct nft_expr_type *__nft_expr_type_get(u8 family,
static int nft_expr_type_request_module(struct net *net, u8 family,
struct nlattr *nla)
{
- nft_request_module(net, "nft-expr-%u-%.*s", family,
- nla_len(nla), (char *)nla_data(nla));
- if (__nft_expr_type_get(family, nla))
+ if (nft_request_module(net, "nft-expr-%u-%.*s", family,
+ nla_len(nla), (char *)nla_data(nla)) == -EAGAIN)
return -EAGAIN;

return 0;
@@ -2041,9 +2049,9 @@ static const struct nft_expr_type *nft_expr_type_get(struct net *net,
if (nft_expr_type_request_module(net, family, nla) == -EAGAIN)
return ERR_PTR(-EAGAIN);

- nft_request_module(net, "nft-expr-%.*s",
- nla_len(nla), (char *)nla_data(nla));
- if (__nft_expr_type_get(family, nla))
+ if (nft_request_module(net, "nft-expr-%.*s",
+ nla_len(nla),
+ (char *)nla_data(nla)) == -EAGAIN)
return ERR_PTR(-EAGAIN);
}
#endif
@@ -2129,6 +2137,13 @@ static int nf_tables_expr_parse(const struct nft_ctx *ctx,
(const struct nlattr * const *)info->tb);
if (IS_ERR(ops)) {
err = PTR_ERR(ops);
+#ifdef CONFIG_MODULES
+ if (err == -EAGAIN)
+ if (nft_expr_type_request_module(ctx->net,
+ ctx->family,
+ tb[NFTA_EXPR_NAME]) != -EAGAIN)
+ err = -ENOENT;
+#endif
goto err1;
}
} else
@@ -2910,8 +2925,7 @@ nft_select_set_ops(const struct nft_ctx *ctx,
lockdep_nfnl_nft_mutex_not_held();
#ifdef CONFIG_MODULES
if (list_empty(&nf_tables_set_types)) {
- nft_request_module(ctx->net, "nft-set");
- if (!list_empty(&nf_tables_set_types))
+ if (nft_request_module(ctx->net, "nft-set") == -EAGAIN)
return ERR_PTR(-EAGAIN);
}
#endif
@@ -5003,8 +5017,7 @@ nft_obj_type_get(struct net *net, u32 objtype)
lockdep_nfnl_nft_mutex_not_held();
#ifdef CONFIG_MODULES
if (type == NULL) {
- nft_request_module(net, "nft-obj-%u", objtype);
- if (__nft_obj_type_get(objtype))
+ if (nft_request_module(net, "nft-obj-%u", objtype) == -EAGAIN)
return ERR_PTR(-EAGAIN);
}
#endif
@@ -5558,8 +5571,7 @@ nft_flowtable_type_get(struct net *net, u8 family)
lockdep_nfnl_nft_mutex_not_held();
#ifdef CONFIG_MODULES
if (type == NULL) {
- nft_request_module(net, "nf-flowtable-%u", family);
- if (__nft_flowtable_type_get(family))
+ if (nft_request_module(net, "nf-flowtable-%u", family) == -EAGAIN)
return ERR_PTR(-EAGAIN);
}
#endif
@@ -6466,6 +6478,18 @@ static void nft_chain_del(struct nft_chain *chain)
list_del_rcu(&chain->list);
}

+static void nf_tables_module_autoload_cleanup(struct net *net)
+{
+ struct nft_module_request *req, *next;
+
+ WARN_ON_ONCE(!list_empty(&net->nft.commit_list));
+ list_for_each_entry_safe(req, next, &net->nft.module_list, list) {
+ WARN_ON_ONCE(!req->done);
+ list_del(&req->list);
+ kfree(req);
+ }
+}
+
static void nf_tables_commit_release(struct net *net)
{
struct nft_trans *trans;
@@ -6478,6 +6502,7 @@ static void nf_tables_commit_release(struct net *net)
* to prevent expensive synchronize_rcu() in commit phase.
*/
if (list_empty(&net->nft.commit_list)) {
+ nf_tables_module_autoload_cleanup(net);
mutex_unlock(&net->nft.commit_mutex);
return;
}
@@ -6492,6 +6517,7 @@ static void nf_tables_commit_release(struct net *net)
list_splice_tail_init(&net->nft.commit_list, &nf_tables_destroy_list);
spin_unlock(&nf_tables_destroy_list_lock);

+ nf_tables_module_autoload_cleanup(net);
mutex_unlock(&net->nft.commit_mutex);

schedule_work(&trans_destroy_work);
@@ -6664,6 +6690,26 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
return 0;
}

+static void nf_tables_module_autoload(struct net *net)
+{
+ struct nft_module_request *req, *next;
+ LIST_HEAD(module_list);
+
+ list_splice_init(&net->nft.module_list, &module_list);
+ mutex_unlock(&net->nft.commit_mutex);
+ list_for_each_entry_safe(req, next, &module_list, list) {
+ if (req->done) {
+ list_del(&req->list);
+ kfree(req);
+ } else {
+ request_module("%s", req->module);
+ req->done = true;
+ }
+ }
+ mutex_lock(&net->nft.commit_mutex);
+ list_splice(&module_list, &net->nft.module_list);
+}
+
static void nf_tables_abort_release(struct nft_trans *trans)
{
switch (trans->msg_type) {
@@ -6693,7 +6739,7 @@ static void nf_tables_abort_release(struct nft_trans *trans)
kfree(trans);
}

-static int __nf_tables_abort(struct net *net)
+static int __nf_tables_abort(struct net *net, bool autoload)
{
struct nft_trans *trans, *next;
struct nft_trans_elem *te;
@@ -6810,6 +6856,11 @@ static int __nf_tables_abort(struct net *net)
nf_tables_abort_release(trans);
}

+ if (autoload)
+ nf_tables_module_autoload(net);
+ else
+ nf_tables_module_autoload_cleanup(net);
+
return 0;
}

@@ -6818,9 +6869,9 @@ static void nf_tables_cleanup(struct net *net)
nft_validate_state_update(net, NFT_VALIDATE_SKIP);
}

-static int nf_tables_abort(struct net *net, struct sk_buff *skb)
+static int nf_tables_abort(struct net *net, struct sk_buff *skb, bool autoload)
{
- int ret = __nf_tables_abort(net);
+ int ret = __nf_tables_abort(net, autoload);

mutex_unlock(&net->nft.commit_mutex);

@@ -7414,6 +7465,7 @@ static int __net_init nf_tables_init_net(struct net *net)
{
INIT_LIST_HEAD(&net->nft.tables);
INIT_LIST_HEAD(&net->nft.commit_list);
+ INIT_LIST_HEAD(&net->nft.module_list);
mutex_init(&net->nft.commit_mutex);
net->nft.base_seq = 1;
net->nft.validate_state = NFT_VALIDATE_SKIP;
@@ -7425,7 +7477,7 @@ static void __net_exit nf_tables_exit_net(struct net *net)
{
mutex_lock(&net->nft.commit_mutex);
if (!list_empty(&net->nft.commit_list))
- __nf_tables_abort(net);
+ __nf_tables_abort(net, false);
__nft_release_tables(net);
mutex_unlock(&net->nft.commit_mutex);
WARN_ON_ONCE(!list_empty(&net->nft.tables));
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index 9bacddc761ba..7454f135e19d 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -478,7 +478,7 @@ static void nfnetlink_rcv_batch(struct sk_buff *skb, struct nlmsghdr *nlh,
}
done:
if (status & NFNL_BATCH_REPLAY) {
- ss->abort(net, oskb);
+ ss->abort(net, oskb, true);
nfnl_err_reset(&err_list);
kfree_skb(skb);
module_put(ss->owner);
@@ -489,11 +489,11 @@ static void nfnetlink_rcv_batch(struct sk_buff *skb, struct nlmsghdr *nlh,
status |= NFNL_BATCH_REPLAY;
goto done;
} else if (err) {
- ss->abort(net, oskb);
+ ss->abort(net, oskb, false);
netlink_ack(oskb, nlmsg_hdr(oskb), err, NULL);
}
} else {
- ss->abort(net, oskb);
+ ss->abort(net, oskb, false);
}
if (ss->cleanup)
ss->cleanup(net);
--
2.34.1


Re: [PATCH 4.19.y-cip 2/6] Backport netfilter: nf_tables: autoload modules from the abort path

Fong, Amy
 

From 185a61df95c18e5111df5ba439b0e60a8a6e40cb Mon Sep 17 00:00:00 2001
From: Pablo Neira Ayuso <pablo@...>
Date: Fri, 5 Jul 2019 23:38:46 +0200
Subject: [PATCH 2/5] netfilter: nf_tables: add nft_expr_type_request_module()

This helper function makes sure the family specific extension is loaded.

Signed-off-by: Pablo Neira Ayuso <pablo@...>
(cherry picked from commit b9c04ae7907f09c5e873e7c9a8feea2ce41e15b3)
---
net/netfilter/nf_tables_api.c | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 02e577e8fb8a..8ec38de1f7a1 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -2009,6 +2009,19 @@ static const struct nft_expr_type *__nft_expr_type_get(u8 family,
return NULL;
}

+#ifdef CONFIG_MODULES
+static int nft_expr_type_request_module(struct net *net, u8 family,
+ struct nlattr *nla)
+{
+ nft_request_module(net, "nft-expr-%u-%.*s", family,
+ nla_len(nla), (char *)nla_data(nla));
+ if (__nft_expr_type_get(family, nla))
+ return -EAGAIN;
+
+ return 0;
+}
+#endif
+
static const struct nft_expr_type *nft_expr_type_get(struct net *net,
u8 family,
struct nlattr *nla)
@@ -2025,9 +2038,7 @@ static const struct nft_expr_type *nft_expr_type_get(struct net *net,
lockdep_nfnl_nft_mutex_not_held();
#ifdef CONFIG_MODULES
if (type == NULL) {
- nft_request_module(net, "nft-expr-%u-%.*s", family,
- nla_len(nla), (char *)nla_data(nla));
- if (__nft_expr_type_get(family, nla))
+ if (nft_expr_type_request_module(net, family, nla) == -EAGAIN)
return ERR_PTR(-EAGAIN);

nft_request_module(net, "nft-expr-%.*s",
--
2.34.1


Re: [PATCH 4.19.y-cip 1/6] Backport netfilter: nf_tables: autoload modules from the abort path

Fong, Amy
 

From dda33be9e3fadf0b47e2afc8a0b381c3667622c3 Mon Sep 17 00:00:00 2001
From: Florian Westphal <fw@...>
Date: Wed, 29 Aug 2018 14:41:32 +0200
Subject: [PATCH 1/5] netfilter: nf_tables: asynchronous release

Release the committed transaction log from a work queue, moving
expensive synchronize_rcu out of the locked section and providing
opportunity to batch this.

On my test machine this cuts runtime of nft-test.py in half.
Based on earlier patch from Pablo Neira Ayuso.

Signed-off-by: Florian Westphal <fw@...>
Signed-off-by: Pablo Neira Ayuso <pablo@...>
(cherry picked from commit 0935d558840099b3679c67bb7468dc78fcbad940)
---
include/net/netfilter/nf_tables.h | 2 ++
net/netfilter/nf_tables_api.c | 56 +++++++++++++++++++++++++++----
2 files changed, 52 insertions(+), 6 deletions(-)

diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 93253ba1eeac..c60d281c9a58 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -1316,12 +1316,14 @@ static inline void nft_set_elem_clear_busy(struct nft_set_ext *ext)
*
* @list: used internally
* @msg_type: message type
+ * @put_net: ctx->net needs to be put
* @ctx: transaction context
* @data: internal information related to the transaction
*/
struct nft_trans {
struct list_head list;
int msg_type;
+ bool put_net;
struct nft_ctx ctx;
char data[0];
};
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 9cc8e92f4b00..02e577e8fb8a 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -29,6 +29,8 @@
static LIST_HEAD(nf_tables_expressions);
static LIST_HEAD(nf_tables_objects);
static LIST_HEAD(nf_tables_flowtables);
+static LIST_HEAD(nf_tables_destroy_list);
+static DEFINE_SPINLOCK(nf_tables_destroy_list_lock);
static u64 table_handle;

enum {
@@ -66,6 +68,8 @@ static void nft_validate_state_update(struct net *net, u8 new_validate_state)

net->nft.validate_state = new_validate_state;
}
+static void nf_tables_trans_destroy_work(struct work_struct *w);
+static DECLARE_WORK(trans_destroy_work, nf_tables_trans_destroy_work);

static void nft_ctx_init(struct nft_ctx *ctx,
struct net *net,
@@ -2503,7 +2507,6 @@ static void nf_tables_rule_destroy(const struct nft_ctx *ctx,
{
struct nft_expr *expr, *next;

- lockdep_assert_held(&ctx->net->nft.commit_mutex);
/*
* Careful: some expressions might not be initialized in case this
* is called on error from nf_tables_newrule().
@@ -6300,19 +6303,28 @@ static void nft_commit_release(struct nft_trans *trans)
nf_tables_flowtable_destroy(nft_trans_flowtable(trans));
break;
}
+
+ if (trans->put_net)
+ put_net(trans->ctx.net);
+
kfree(trans);
}

-static void nf_tables_commit_release(struct net *net)
+static void nf_tables_trans_destroy_work(struct work_struct *w)
{
struct nft_trans *trans, *next;
+ LIST_HEAD(head);
+
+ spin_lock(&nf_tables_destroy_list_lock);
+ list_splice_init(&nf_tables_destroy_list, &head);
+ spin_unlock(&nf_tables_destroy_list_lock);

- if (list_empty(&net->nft.commit_list))
+ if (list_empty(&head))
return;

synchronize_rcu();

- list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) {
+ list_for_each_entry_safe(trans, next, &head, list) {
list_del(&trans->list);
nft_commit_release(trans);
}
@@ -6443,6 +6455,37 @@ static void nft_chain_del(struct nft_chain *chain)
list_del_rcu(&chain->list);
}

+static void nf_tables_commit_release(struct net *net)
+{
+ struct nft_trans *trans;
+
+ /* all side effects have to be made visible.
+ * For example, if a chain named 'foo' has been deleted, a
+ * new transaction must not find it anymore.
+ *
+ * Memory reclaim happens asynchronously from work queue
+ * to prevent expensive synchronize_rcu() in commit phase.
+ */
+ if (list_empty(&net->nft.commit_list)) {
+ mutex_unlock(&net->nft.commit_mutex);
+ return;
+ }
+
+ trans = list_last_entry(&net->nft.commit_list,
+ struct nft_trans, list);
+ get_net(trans->ctx.net);
+ WARN_ON_ONCE(trans->put_net);
+
+ trans->put_net = true;
+ spin_lock(&nf_tables_destroy_list_lock);
+ list_splice_tail_init(&net->nft.commit_list, &nf_tables_destroy_list);
+ spin_unlock(&nf_tables_destroy_list_lock);
+
+ mutex_unlock(&net->nft.commit_mutex);
+
+ schedule_work(&trans_destroy_work);
+}
+
static int nf_tables_commit(struct net *net, struct sk_buff *skb)
{
struct nft_trans *trans, *next;
@@ -6604,9 +6647,8 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
}
}

- nf_tables_commit_release(net);
nf_tables_gen_notify(net, skb, NFT_MSG_NEWGEN);
- mutex_unlock(&net->nft.commit_mutex);
+ nf_tables_commit_release(net);

return 0;
}
@@ -7387,6 +7429,7 @@ static int __init nf_tables_module_init(void)
{
int err;

+ spin_lock_init(&nf_tables_destroy_list_lock);
err = register_pernet_subsys(&nf_tables_net_ops);
if (err < 0)
return err;
@@ -7426,6 +7469,7 @@ static void __exit nf_tables_module_exit(void)
unregister_netdevice_notifier(&nf_tables_flowtable_notifier);
nft_chain_filter_fini();
unregister_pernet_subsys(&nf_tables_net_ops);
+ cancel_work_sync(&trans_destroy_work);
rcu_barrier();
nf_tables_core_module_exit();
}
--
2.34.1


[PATCH 4.19.y-cip 0/6] Backport netfilter: nf_tables: autoload modules from the abort path

Fong, Amy
 

The following series backports netfilter: nf_tables: autoload modules from abort path
which fixes the bug mentioned in the following:

https://syzkaller.appspot.com/bug?extid=437bf61d165c87bd40fb


----

BUG: corrupted list in __nf_tables_abort
Status: fixed on 2020/03/17 22:09
Reported-by: syzbot+437bf61d165c87bd40fb@...
Fix commit: eb014de4fd41 netfilter: nf_tables: autoload modules from the abort path
First crash: 717d, last: 710d

Cause bisection: introduced by (bisect log) :
commit ec7470b834fe7b5d7eff11b6677f5d7fdf5e9a91
Author: Pablo Neira Ayuso <pablo@...>
Date: Mon Jan 13 17:09:58 2020 +0000

netfilter: nf_tables: store transaction list locally while requesting module

Crash: KASAN: use-after-free Read in __nf_tables_abort (log)
Repro: C syz .config

Fix bisection: fixed by (bisect log) :
commit 34682110abc50ffea7e002b0c2fd7ea9e0000ccc
Author: Max Chou <max.chou@...>
Date: Wed Nov 27 03:01:07 2019 +0000

Bluetooth: btusb: Edit the logical value for Realtek Bluetooth reset


[PATCH 5.10.y-cip 61/61] arm64: dts: renesas: rzg2l-smarc-som: Enable Ethernet

Lad Prabhakar
 

From: Biju Das <biju.das.jz@...>

commit 361b0dcbd7f9b01d92fdcb032ed4e020941183eb upstream.

Enable Ethernet{0,1} interfaces on RZ/G2L SMARC EVK.

Signed-off-by: Biju Das <biju.das.jz@...>
Link: https://lore.kernel.org/r/20211013075647.32231-3-biju.das.jz@bp.renesas.com
Signed-off-by: Geert Uytterhoeven <geert+renesas@...>
[PL: manually applied the changes]
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
---
.../boot/dts/renesas/rzg2l-smarc-som.dtsi | 97 +++++++++++++++++++
arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi | 1 -
2 files changed, 97 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/renesas/rzg2l-smarc-som.dtsi b/arch/arm64/boot/dts/renesas/rzg2l-smarc-som.dtsi
index da1ee2206e1a..1fd961066236 100644
--- a/arch/arm64/boot/dts/renesas/rzg2l-smarc-som.dtsi
+++ b/arch/arm64/boot/dts/renesas/rzg2l-smarc-som.dtsi
@@ -8,6 +8,15 @@
#include <dt-bindings/pinctrl/rzg2l-pinctrl.h>

/ {
+ aliases {
+ ethernet0 = &eth0;
+ ethernet1 = &eth1;
+ };
+
+ chosen {
+ bootargs = "ignore_loglevel rw root=/dev/nfs ip=on";
+ };
+
memory@48000000 {
device_type = "memory";
/* first 128MB is reserved for secure area. */
@@ -24,6 +33,58 @@
/delete-node/ channel@7;
};

+&eth0 {
+ pinctrl-0 = <&eth0_pins>;
+ pinctrl-names = "default";
+ phy-handle = <&phy0>;
+ phy-mode = "rgmii-id";
+ status = "okay";
+
+ phy0: ethernet-phy@7 {
+ compatible = "ethernet-phy-id0022.1640",
+ "ethernet-phy-ieee802.3-c22";
+ reg = <7>;
+ rxc-skew-psec = <2400>;
+ txc-skew-psec = <2400>;
+ rxdv-skew-psec = <0>;
+ txdv-skew-psec = <0>;
+ rxd0-skew-psec = <0>;
+ rxd1-skew-psec = <0>;
+ rxd2-skew-psec = <0>;
+ rxd3-skew-psec = <0>;
+ txd0-skew-psec = <0>;
+ txd1-skew-psec = <0>;
+ txd2-skew-psec = <0>;
+ txd3-skew-psec = <0>;
+ };
+};
+
+&eth1 {
+ pinctrl-0 = <&eth1_pins>;
+ pinctrl-names = "default";
+ phy-handle = <&phy1>;
+ phy-mode = "rgmii-id";
+ status = "okay";
+
+ phy1: ethernet-phy@7 {
+ compatible = "ethernet-phy-id0022.1640",
+ "ethernet-phy-ieee802.3-c22";
+ reg = <7>;
+ rxc-skew-psec = <2400>;
+ txc-skew-psec = <2400>;
+ rxdv-skew-psec = <0>;
+ txdv-skew-psec = <0>;
+ rxd0-skew-psec = <0>;
+ rxd1-skew-psec = <0>;
+ rxd2-skew-psec = <0>;
+ rxd3-skew-psec = <0>;
+ txd0-skew-psec = <0>;
+ txd1-skew-psec = <0>;
+ txd2-skew-psec = <0>;
+ txd3-skew-psec = <0>;
+ };
+};
+
&extal_clk {
clock-frequency = <24000000>;
};
@@ -32,4 +93,40 @@
adc_pins: adc {
pinmux = <RZG2L_PORT_PINMUX(9, 0, 2)>; /* ADC_TRG */
};
+
+ eth0_pins: eth0 {
+ pinmux = <RZG2L_PORT_PINMUX(28, 1, 1)>, /* ET0_LINKSTA */
+ <RZG2L_PORT_PINMUX(27, 1, 1)>, /* ET0_MDC */
+ <RZG2L_PORT_PINMUX(28, 0, 1)>, /* ET0_MDIO */
+ <RZG2L_PORT_PINMUX(20, 0, 1)>, /* ET0_TXC */
+ <RZG2L_PORT_PINMUX(20, 1, 1)>, /* ET0_TX_CTL */
+ <RZG2L_PORT_PINMUX(20, 2, 1)>, /* ET0_TXD0 */
+ <RZG2L_PORT_PINMUX(21, 0, 1)>, /* ET0_TXD1 */
+ <RZG2L_PORT_PINMUX(21, 1, 1)>, /* ET0_TXD2 */
+ <RZG2L_PORT_PINMUX(22, 0, 1)>, /* ET0_TXD3 */
+ <RZG2L_PORT_PINMUX(24, 0, 1)>, /* ET0_RXC */
+ <RZG2L_PORT_PINMUX(24, 1, 1)>, /* ET0_RX_CTL */
+ <RZG2L_PORT_PINMUX(25, 0, 1)>, /* ET0_RXD0 */
+ <RZG2L_PORT_PINMUX(25, 1, 1)>, /* ET0_RXD1 */
+ <RZG2L_PORT_PINMUX(26, 0, 1)>, /* ET0_RXD2 */
+ <RZG2L_PORT_PINMUX(26, 1, 1)>; /* ET0_RXD3 */
+ };
+
+ eth1_pins: eth1 {
+ pinmux = <RZG2L_PORT_PINMUX(37, 2, 1)>, /* ET1_LINKSTA */
+ <RZG2L_PORT_PINMUX(37, 0, 1)>, /* ET1_MDC */
+ <RZG2L_PORT_PINMUX(37, 1, 1)>, /* ET1_MDIO */
+ <RZG2L_PORT_PINMUX(29, 0, 1)>, /* ET1_TXC */
+ <RZG2L_PORT_PINMUX(29, 1, 1)>, /* ET1_TX_CTL */
+ <RZG2L_PORT_PINMUX(30, 0, 1)>, /* ET1_TXD0 */
+ <RZG2L_PORT_PINMUX(30, 1, 1)>, /* ET1_TXD1 */
+ <RZG2L_PORT_PINMUX(31, 0, 1)>, /* ET1_TXD2 */
+ <RZG2L_PORT_PINMUX(31, 1, 1)>, /* ET1_TXD3 */
+ <RZG2L_PORT_PINMUX(33, 1, 1)>, /* ET1_RXC */
+ <RZG2L_PORT_PINMUX(34, 0, 1)>, /* ET1_RX_CTL */
+ <RZG2L_PORT_PINMUX(34, 1, 1)>, /* ET1_RXD0 */
+ <RZG2L_PORT_PINMUX(35, 0, 1)>, /* ET1_RXD1 */
+ <RZG2L_PORT_PINMUX(35, 1, 1)>, /* ET1_RXD2 */
+ <RZG2L_PORT_PINMUX(36, 0, 1)>; /* ET1_RXD3 */
+ };
};
diff --git a/arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi b/arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi
index f2dc0c0f5fd3..a33594575fc4 100644
--- a/arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi
+++ b/arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi
@@ -17,7 +17,6 @@
};

chosen {
- bootargs = "ignore_loglevel";
stdout-path = "serial0:115200n8";
};

--
2.17.1


[PATCH 5.10.y-cip 60/61] arm64: dts: renesas: r9a07g044: Add GbEthernet nodes

Lad Prabhakar
 

From: Biju Das <biju.das.jz@...>

commit 38ad23e15a02f4001cd0048617f85522c37e0e8a upstream.

Add Gigabit Ethernet{0,1} nodes to SoC DTSI.

Signed-off-by: Biju Das <biju.das.jz@...>
Link: https://lore.kernel.org/r/20211013075647.32231-2-biju.das.jz@bp.renesas.com
Signed-off-by: Geert Uytterhoeven <geert+renesas@...>
[PL: manually applied the changes]
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
---
arch/arm64/boot/dts/renesas/r9a07g044.dtsi | 40 ++++++++++++++++++++++
1 file changed, 40 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r9a07g044.dtsi b/arch/arm64/boot/dts/renesas/r9a07g044.dtsi
index 2fa29d81c2a7..a88d84b95034 100644
--- a/arch/arm64/boot/dts/renesas/r9a07g044.dtsi
+++ b/arch/arm64/boot/dts/renesas/r9a07g044.dtsi
@@ -341,6 +341,46 @@
interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>;
};

+ eth0: ethernet@11c20000 {
+ compatible = "renesas,r9a07g044-gbeth",
+ "renesas,rzg2l-gbeth";
+ reg = <0 0x11c20000 0 0x10000>;
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "mux", "fil", "arp_ns";
+ phy-mode = "rgmii";
+ clocks = <&cpg CPG_MOD R9A07G044_ETH0_CLK_AXI>,
+ <&cpg CPG_MOD R9A07G044_ETH0_CLK_CHI>,
+ <&cpg CPG_CORE R9A07G044_CLK_HP>;
+ clock-names = "axi", "chi", "refclk";
+ resets = <&cpg R9A07G044_ETH0_RST_HW_N>;
+ power-domains = <&cpg>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ eth1: ethernet@11c30000 {
+ compatible = "renesas,r9a07g044-gbeth",
+ "renesas,rzg2l-gbeth";
+ reg = <0 0x11c30000 0 0x10000>;
+ interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "mux", "fil", "arp_ns";
+ phy-mode = "rgmii";
+ clocks = <&cpg CPG_MOD R9A07G044_ETH1_CLK_AXI>,
+ <&cpg CPG_MOD R9A07G044_ETH1_CLK_CHI>,
+ <&cpg CPG_CORE R9A07G044_CLK_HP>;
+ clock-names = "axi", "chi", "refclk";
+ resets = <&cpg R9A07G044_ETH1_RST_HW_N>;
+ power-domains = <&cpg>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
phyrst: usbphy-ctrl@11c40000 {
compatible = "renesas,r9a07g044-usbphy-ctrl",
"renesas,rzg2l-usbphy-ctrl";
--
2.17.1


[PATCH 5.10.y-cip 59/61] clk: renesas: r9a07g044: Add GbEthernet clock/reset

Lad Prabhakar
 

From: Biju Das <biju.das.jz@...>

commit c11d7f5126b7c5da41f8fb7f69fc86fece65b2b3 upstream.

Add ETH{0,1} clock/reset entries to CPG driver.

Signed-off-by: Biju Das <biju.das.jz@...>
Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
Link: https://lore.kernel.org/r/20210922155145.28156-5-biju.das.jz@bp.renesas.com
Signed-off-by: Geert Uytterhoeven <geert+renesas@...>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
---
drivers/clk/renesas/r9a07g044-cpg.c | 10 ++++++++++
1 file changed, 10 insertions(+)

diff --git a/drivers/clk/renesas/r9a07g044-cpg.c b/drivers/clk/renesas/r9a07g044-cpg.c
index ce2c40a0213a..3c518b56c5a6 100644
--- a/drivers/clk/renesas/r9a07g044-cpg.c
+++ b/drivers/clk/renesas/r9a07g044-cpg.c
@@ -138,6 +138,14 @@ static struct rzg2l_mod_clk r9a07g044_mod_clks[] = {
0x578, 2),
DEF_MOD("usb_pclk", R9A07G044_USB_PCLK, R9A07G044_CLK_P1,
0x578, 3),
+ DEF_COUPLED("eth0_axi", R9A07G044_ETH0_CLK_AXI, R9A07G044_CLK_M0,
+ 0x57c, 0),
+ DEF_COUPLED("eth0_chi", R9A07G044_ETH0_CLK_CHI, R9A07G044_CLK_ZT,
+ 0x57c, 0),
+ DEF_COUPLED("eth1_axi", R9A07G044_ETH1_CLK_AXI, R9A07G044_CLK_M0,
+ 0x57c, 1),
+ DEF_COUPLED("eth1_chi", R9A07G044_ETH1_CLK_CHI, R9A07G044_CLK_ZT,
+ 0x57c, 1),
DEF_MOD("i2c0", R9A07G044_I2C0_PCLK, R9A07G044_CLK_P0,
0x580, 0),
DEF_MOD("i2c1", R9A07G044_I2C1_PCLK, R9A07G044_CLK_P0,
@@ -182,6 +190,8 @@ static struct rzg2l_reset r9a07g044_resets[] = {
DEF_RST(R9A07G044_USB_U2H1_HRESETN, 0x878, 1),
DEF_RST(R9A07G044_USB_U2P_EXL_SYSRST, 0x878, 2),
DEF_RST(R9A07G044_USB_PRESETN, 0x878, 3),
+ DEF_RST(R9A07G044_ETH0_RST_HW_N, 0x87c, 0),
+ DEF_RST(R9A07G044_ETH1_RST_HW_N, 0x87c, 1),
DEF_RST(R9A07G044_I2C0_MRST, 0x880, 0),
DEF_RST(R9A07G044_I2C1_MRST, 0x880, 1),
DEF_RST(R9A07G044_I2C2_MRST, 0x880, 2),
--
2.17.1


[PATCH 5.10.y-cip 58/61] clk: renesas: r9a07g044: Add ethernet clock sources

Lad Prabhakar
 

From: Biju Das <biju.das.jz@...>

commit 70a4af3662e073768a68a7ed5a82f49677cbde0c upstream.

Ethernet reference clock can be sourced from PLL5_FOUT3 or PLL6. Add
support for ethernet source clock selection using SEL_PLL_6_2 mux.

This patch also renames the PLL5_DIV2 core clock to PLL5_250 to match
with the register description as mentioned in RZ/G2L HW manual (Rev.1.00).

Signed-off-by: Biju Das <biju.das.jz@...>
Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
Link: https://lore.kernel.org/r/20210922155145.28156-3-biju.das.jz@bp.renesas.com
Signed-off-by: Geert Uytterhoeven <geert+renesas@...>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
---
drivers/clk/renesas/r9a07g044-cpg.c | 19 ++++++++++++++++++-
drivers/clk/renesas/rzg2l-cpg.h | 3 +++
2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/renesas/r9a07g044-cpg.c b/drivers/clk/renesas/r9a07g044-cpg.c
index 1490446985e2..ce2c40a0213a 100644
--- a/drivers/clk/renesas/r9a07g044-cpg.c
+++ b/drivers/clk/renesas/r9a07g044-cpg.c
@@ -35,8 +35,10 @@ enum clk_ids {
CLK_PLL3_DIV4,
CLK_PLL4,
CLK_PLL5,
- CLK_PLL5_DIV2,
+ CLK_PLL5_FOUT3,
+ CLK_PLL5_250,
CLK_PLL6,
+ CLK_PLL6_250,
CLK_P1_DIV2,

/* Module Clocks */
@@ -53,6 +55,9 @@ static const struct clk_div_table dtable_1_32[] = {
{0, 0},
};

+/* Mux clock tables */
+static const char * const sel_pll6_2[] = { ".pll6_250", ".pll5_250" };
+
static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = {
/* External Clock Inputs */
DEF_INPUT("extal", CLK_EXTAL),
@@ -64,6 +69,11 @@ static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = {
DEF_FIXED(".pll2", CLK_PLL2, CLK_EXTAL, 133, 2),
DEF_FIXED(".pll3", CLK_PLL3, CLK_EXTAL, 133, 2),

+ DEF_FIXED(".pll5", CLK_PLL5, CLK_EXTAL, 125, 1),
+ DEF_FIXED(".pll5_fout3", CLK_PLL5_FOUT3, CLK_PLL5, 1, 6),
+
+ DEF_FIXED(".pll6", CLK_PLL6, CLK_EXTAL, 125, 6),
+
DEF_FIXED(".pll2_div2", CLK_PLL2_DIV2, CLK_PLL2, 1, 2),
DEF_FIXED(".pll2_div16", CLK_PLL2_DIV16, CLK_PLL2, 1, 16),
DEF_FIXED(".pll2_div20", CLK_PLL2_DIV20, CLK_PLL2, 1, 20),
@@ -73,6 +83,9 @@ static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = {
DEF_FIXED(".pll3_div2_4_2", CLK_PLL3_DIV2_4_2, CLK_PLL3_DIV2_4, 1, 2),
DEF_FIXED(".pll3_div4", CLK_PLL3_DIV4, CLK_PLL3, 1, 4),

+ DEF_FIXED(".pll5_250", CLK_PLL5_250, CLK_PLL5_FOUT3, 1, 2),
+ DEF_FIXED(".pll6_250", CLK_PLL6_250, CLK_PLL6, 1, 2),
+
/* Core output clk */
DEF_FIXED("I", R9A07G044_CLK_I, CLK_PLL1, 1, 1),
DEF_DIV("P0", R9A07G044_CLK_P0, CLK_PLL2_DIV16, DIVPL2A,
@@ -84,6 +97,10 @@ static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = {
DEF_FIXED("P1_DIV2", CLK_P1_DIV2, R9A07G044_CLK_P1, 1, 2),
DEF_DIV("P2", R9A07G044_CLK_P2, CLK_PLL3_DIV2_4_2,
DIVPL3A, dtable_1_32, CLK_DIVIDER_HIWORD_MASK),
+ DEF_FIXED("M0", R9A07G044_CLK_M0, CLK_PLL3_DIV2_4, 1, 1),
+ DEF_FIXED("ZT", R9A07G044_CLK_ZT, CLK_PLL3_DIV2_4_2, 1, 1),
+ DEF_MUX("HP", R9A07G044_CLK_HP, SEL_PLL6_2,
+ sel_pll6_2, ARRAY_SIZE(sel_pll6_2), 0, CLK_MUX_HIWORD_MASK),
};

static struct rzg2l_mod_clk r9a07g044_mod_clks[] = {
diff --git a/drivers/clk/renesas/rzg2l-cpg.h b/drivers/clk/renesas/rzg2l-cpg.h
index ebf716bb913e..191c403aa52f 100644
--- a/drivers/clk/renesas/rzg2l-cpg.h
+++ b/drivers/clk/renesas/rzg2l-cpg.h
@@ -11,6 +11,7 @@

#define CPG_PL2_DDIV (0x204)
#define CPG_PL3A_DDIV (0x208)
+#define CPG_PL6_ETH_SSEL (0x418)

/* n = 0/1/2 for PLL1/4/6 */
#define CPG_SAMPLL_CLK1(n) (0x04 + (16 * n))
@@ -27,6 +28,8 @@
#define SEL_PLL_PACK(offset, bitpos, size) \
(((offset) << 20) | ((bitpos) << 12) | ((size) << 8))

+#define SEL_PLL6_2 SEL_PLL_PACK(CPG_PL6_ETH_SSEL, 0, 1)
+
/**
* Definitions of CPG Core Clocks
*
--
2.17.1


[PATCH 5.10.y-cip 57/61] ravb: Fix typo AVB->DMAC

Lad Prabhakar
 

From: Biju Das <biju.das.jz@...>

commit 9404092646473180ef16198f0502da050fc0fa61 upstream.

Fix the typo AVB->DMAC in comment, as the code following the comment
is for DMAC on Gigabit Ethernet IP.

Signed-off-by: Biju Das <biju.das.jz@...>
Suggested-by: Sergey Shtylyov <s.shtylyov@...>
Reviewed-by: Sergey Shtylyov <s.shtylyov@...>
Signed-off-by: Jakub Kicinski <kuba@...>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
---
drivers/net/ethernet/renesas/ravb_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
index dc639ff1a395..ea76fd98a767 100644
--- a/drivers/net/ethernet/renesas/ravb_main.c
+++ b/drivers/net/ethernet/renesas/ravb_main.c
@@ -586,7 +586,7 @@ static int ravb_dmac_init_gbeth(struct net_device *ndev)
/* Descriptor format */
ravb_ring_format(ndev, RAVB_BE);

- /* Set AVB RX */
+ /* Set DMAC RX */
ravb_write(ndev, 0x60000000, RCR);

/* Set Max Frame Length (RTC) */
--
2.17.1


[PATCH 5.10.y-cip 56/61] ravb: Update ravb_emac_init_gbeth()

Lad Prabhakar
 

From: Biju Das <biju.das.jz@...>

commit 3d6b24a2ada3d53f7da9362d03856bdec74806e5 upstream.

This patch enables Receive/Transmit port of TOE and removes
the setting of promiscuous bit from EMAC configuration mode register.

This patch also update EMAC configuration mode comment from
"PAUSE prohibition" to "EMAC Mode: PAUSE prohibition; Duplex; TX;
RX; CRC Pass Through".

Signed-off-by: Biju Das <biju.das.jz@...>
Reviewed-by: Sergey Shtylyov <s.shtylyov@...>
Signed-off-by: Jakub Kicinski <kuba@...>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
---
drivers/net/ethernet/renesas/ravb.h | 6 ++++++
drivers/net/ethernet/renesas/ravb_main.c | 5 +++--
2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/renesas/ravb.h b/drivers/net/ethernet/renesas/ravb.h
index 5d07732ef35a..0b5801f7e961 100644
--- a/drivers/net/ethernet/renesas/ravb.h
+++ b/drivers/net/ethernet/renesas/ravb.h
@@ -204,6 +204,7 @@ enum ravb_reg {
TLFRCR = 0x0758,
RFCR = 0x0760,
MAFCR = 0x0778,
+ CSR0 = 0x0800, /* RZ/G2L only */
};


@@ -964,6 +965,11 @@ enum CXR31_BIT {
CXR31_SEL_LINK1 = 0x00000008,
};

+enum CSR0_BIT {
+ CSR0_TPE = 0x00000010,
+ CSR0_RPE = 0x00000020,
+};
+
#define DBAT_ENTRY_NUM 22
#define RX_QUEUE_OFFSET 4
#define NUM_RX_QUEUE 2
diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
index a02ea91c81f5..dc639ff1a395 100644
--- a/drivers/net/ethernet/renesas/ravb_main.c
+++ b/drivers/net/ethernet/renesas/ravb_main.c
@@ -517,10 +517,10 @@ static void ravb_emac_init_gbeth(struct net_device *ndev)
/* Receive frame limit set register */
ravb_write(ndev, GBETH_RX_BUFF_MAX + ETH_FCS_LEN, RFLR);

- /* PAUSE prohibition */
+ /* EMAC Mode: PAUSE prohibition; Duplex; TX; RX; CRC Pass Through */
ravb_write(ndev, ECMR_ZPF | ((priv->duplex > 0) ? ECMR_DM : 0) |
ECMR_TE | ECMR_RE | ECMR_RCPT |
- ECMR_TXF | ECMR_RXF | ECMR_PRM, ECMR);
+ ECMR_TXF | ECMR_RXF, ECMR);

ravb_set_rate_gbeth(ndev);

@@ -532,6 +532,7 @@ static void ravb_emac_init_gbeth(struct net_device *ndev)

/* E-MAC status register clear */
ravb_write(ndev, ECSR_ICD | ECSR_LCHNG | ECSR_PFRI, ECSR);
+ ravb_write(ndev, CSR0_TPE | CSR0_RPE, CSR0);

/* E-MAC interrupt enable register */
ravb_write(ndev, ECSIPR_ICDIP, ECSIPR);
--
2.17.1


[PATCH 5.10.y-cip 55/61] ravb: Rename "nc_queue" feature bit

Lad Prabhakar
 

From: Biju Das <biju.das.jz@...>

commit 1091da579d7ccdba887bdfd11e31a23be694bbd0 upstream.

Rename the feature bit "nc_queue" with "nc_queues" as AVB DMAC has
RX and TX NC queues.

There is no functional change.

Signed-off-by: Biju Das <biju.das.jz@...>
Suggested-by: Sergey Shtylyov <s.shtylyov@...>
Reviewed-by: Sergey Shtylyov <s.shtylyov@...>
Signed-off-by: Jakub Kicinski <kuba@...>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
---
drivers/net/ethernet/renesas/ravb.h | 2 +-
drivers/net/ethernet/renesas/ravb_main.c | 36 ++++++++++++------------
2 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/drivers/net/ethernet/renesas/ravb.h b/drivers/net/ethernet/renesas/ravb.h
index 99d666a5fb49..5d07732ef35a 100644
--- a/drivers/net/ethernet/renesas/ravb.h
+++ b/drivers/net/ethernet/renesas/ravb.h
@@ -1023,7 +1023,7 @@ struct ravb_hw_info {
unsigned multi_irqs:1; /* AVB-DMAC and E-MAC has multiple irqs */
unsigned gptp:1; /* AVB-DMAC has gPTP support */
unsigned ccc_gac:1; /* AVB-DMAC has gPTP support active in config mode */
- unsigned nc_queue:1; /* AVB-DMAC has NC queue */
+ unsigned nc_queues:1; /* AVB-DMAC has RX and TX NC queues */
unsigned magic_pkt:1; /* E-MAC supports magic packet detection */
unsigned half_duplex:1; /* E-MAC supports half duplex mode */
};
diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
index 9de47566feef..a02ea91c81f5 100644
--- a/drivers/net/ethernet/renesas/ravb_main.c
+++ b/drivers/net/ethernet/renesas/ravb_main.c
@@ -1174,7 +1174,7 @@ static irqreturn_t ravb_interrupt(int irq, void *dev_id)
result = IRQ_HANDLED;

/* Network control and best effort queue RX/TX */
- if (info->nc_queue) {
+ if (info->nc_queues) {
for (q = RAVB_NC; q >= RAVB_BE; q--) {
if (ravb_queue_interrupt(ndev, q))
result = IRQ_HANDLED;
@@ -1313,7 +1313,7 @@ static int ravb_poll(struct napi_struct *napi, int budget)

/* Receive error message handling */
priv->rx_over_errors = priv->stats[RAVB_BE].rx_over_errors;
- if (info->nc_queue)
+ if (info->nc_queues)
priv->rx_over_errors += priv->stats[RAVB_NC].rx_over_errors;
if (priv->rx_over_errors != ndev->stats.rx_over_errors)
ndev->stats.rx_over_errors = priv->rx_over_errors;
@@ -1564,7 +1564,7 @@ static void ravb_get_ethtool_stats(struct net_device *ndev,
int i = 0;
int q;

- num_rx_q = info->nc_queue ? NUM_RX_QUEUE : 1;
+ num_rx_q = info->nc_queues ? NUM_RX_QUEUE : 1;
/* Device-specific stats */
for (q = RAVB_BE; q < num_rx_q; q++) {
struct net_device_stats *stats = &priv->stats[q];
@@ -1641,7 +1641,7 @@ static int ravb_set_ringparam(struct net_device *ndev,

/* Free all the skb's in the RX queue and the DMA buffers. */
ravb_ring_free(ndev, RAVB_BE);
- if (info->nc_queue)
+ if (info->nc_queues)
ravb_ring_free(ndev, RAVB_NC);
}

@@ -1761,7 +1761,7 @@ static int ravb_open(struct net_device *ndev)
int error;

napi_enable(&priv->napi[RAVB_BE]);
- if (info->nc_queue)
+ if (info->nc_queues)
napi_enable(&priv->napi[RAVB_NC]);

if (!info->multi_irqs) {
@@ -1836,7 +1836,7 @@ static int ravb_open(struct net_device *ndev)
out_free_irq:
free_irq(ndev->irq, ndev);
out_napi_off:
- if (info->nc_queue)
+ if (info->nc_queues)
napi_disable(&priv->napi[RAVB_NC]);
napi_disable(&priv->napi[RAVB_BE]);
return error;
@@ -1886,7 +1886,7 @@ static void ravb_tx_timeout_work(struct work_struct *work)
}

ravb_ring_free(ndev, RAVB_BE);
- if (info->nc_queue)
+ if (info->nc_queues)
ravb_ring_free(ndev, RAVB_NC);

/* Device init */
@@ -2086,7 +2086,7 @@ static struct net_device_stats *ravb_get_stats(struct net_device *ndev)
nstats->rx_length_errors = stats0->rx_length_errors;
nstats->rx_missed_errors = stats0->rx_missed_errors;
nstats->rx_over_errors = stats0->rx_over_errors;
- if (info->nc_queue) {
+ if (info->nc_queues) {
stats1 = &priv->stats[RAVB_NC];

nstats->rx_packets += stats1->rx_packets;
@@ -2167,13 +2167,13 @@ static int ravb_close(struct net_device *ndev)
}
free_irq(ndev->irq, ndev);

- if (info->nc_queue)
+ if (info->nc_queues)
napi_disable(&priv->napi[RAVB_NC]);
napi_disable(&priv->napi[RAVB_BE]);

/* Free all the skb's in the RX queue and the DMA buffers. */
ravb_ring_free(ndev, RAVB_BE);
- if (info->nc_queue)
+ if (info->nc_queues)
ravb_ring_free(ndev, RAVB_NC);

return 0;
@@ -2413,7 +2413,7 @@ static const struct ravb_hw_info ravb_gen3_hw_info = {
.tx_counters = 1,
.multi_irqs = 1,
.ccc_gac = 1,
- .nc_queue = 1,
+ .nc_queues = 1,
.magic_pkt = 1,
};

@@ -2436,7 +2436,7 @@ static const struct ravb_hw_info ravb_gen2_hw_info = {
.rx_max_buf_size = SZ_2K,
.aligned_tx = 1,
.gptp = 1,
- .nc_queue = 1,
+ .nc_queues = 1,
.magic_pkt = 1,
};

@@ -2616,7 +2616,7 @@ static int ravb_probe(struct platform_device *pdev)
priv->pdev = pdev;
priv->num_tx_ring[RAVB_BE] = BE_TX_RING_SIZE;
priv->num_rx_ring[RAVB_BE] = BE_RX_RING_SIZE;
- if (info->nc_queue) {
+ if (info->nc_queues) {
priv->num_tx_ring[RAVB_NC] = NC_TX_RING_SIZE;
priv->num_rx_ring[RAVB_NC] = NC_RX_RING_SIZE;
}
@@ -2752,7 +2752,7 @@ static int ravb_probe(struct platform_device *pdev)
}

netif_napi_add(ndev, &priv->napi[RAVB_BE], ravb_poll, 64);
- if (info->nc_queue)
+ if (info->nc_queues)
netif_napi_add(ndev, &priv->napi[RAVB_NC], ravb_poll, 64);

/* Network device register */
@@ -2771,7 +2771,7 @@ static int ravb_probe(struct platform_device *pdev)
return 0;

out_napi_del:
- if (info->nc_queue)
+ if (info->nc_queues)
netif_napi_del(&priv->napi[RAVB_NC]);

netif_napi_del(&priv->napi[RAVB_BE]);
@@ -2812,7 +2812,7 @@ static int ravb_remove(struct platform_device *pdev)
ravb_write(ndev, CCC_OPC_RESET, CCC);
pm_runtime_put_sync(&pdev->dev);
unregister_netdev(ndev);
- if (info->nc_queue)
+ if (info->nc_queues)
netif_napi_del(&priv->napi[RAVB_NC]);
netif_napi_del(&priv->napi[RAVB_BE]);
ravb_mdio_release(priv);
@@ -2836,7 +2836,7 @@ static int ravb_wol_setup(struct net_device *ndev)

/* Only allow ECI interrupts */
synchronize_irq(priv->emac_irq);
- if (info->nc_queue)
+ if (info->nc_queues)
napi_disable(&priv->napi[RAVB_NC]);
napi_disable(&priv->napi[RAVB_BE]);
ravb_write(ndev, ECSIPR_MPDIP, ECSIPR);
@@ -2853,7 +2853,7 @@ static int ravb_wol_restore(struct net_device *ndev)
const struct ravb_hw_info *info = priv->info;
int ret;

- if (info->nc_queue)
+ if (info->nc_queues)
napi_enable(&priv->napi[RAVB_NC]);
napi_enable(&priv->napi[RAVB_BE]);

--
2.17.1


[PATCH 5.10.y-cip 54/61] ravb: Optimize ravb_emac_init_gbeth function

Lad Prabhakar
 

From: Biju Das <biju.das.jz@...>

commit 030634f37db996f5b8cc82f43ed6e3b6b009d56c upstream.

Optimize CXR31 register initialization on ravb_emac_init_gbeth
function.

Signed-off-by: Biju Das <biju.das.jz@...>
Suggested-by: Sergey Shtylyov <s.shtylyov@...>
Reviewed-by: Sergey Shtylyov <s.shtylyov@...>
Signed-off-by: Jakub Kicinski <kuba@...>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
---
drivers/net/ethernet/renesas/ravb_main.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
index ab57b72ea1cc..9de47566feef 100644
--- a/drivers/net/ethernet/renesas/ravb_main.c
+++ b/drivers/net/ethernet/renesas/ravb_main.c
@@ -536,8 +536,7 @@ static void ravb_emac_init_gbeth(struct net_device *ndev)
/* E-MAC interrupt enable register */
ravb_write(ndev, ECSIPR_ICDIP, ECSIPR);

- ravb_modify(ndev, CXR31, CXR31_SEL_LINK1, 0);
- ravb_modify(ndev, CXR31, CXR31_SEL_LINK0, CXR31_SEL_LINK0);
+ ravb_modify(ndev, CXR31, CXR31_SEL_LINK0 | CXR31_SEL_LINK1, CXR31_SEL_LINK0);
}

static void ravb_emac_init_rcar(struct net_device *ndev)
--
2.17.1


[PATCH 5.10.y-cip 53/61] ravb: Rename "tsrq" variable

Lad Prabhakar
 

From: Biju Das <biju.das.jz@...>

commit 4ea3167bad275afda5a0b5a794831b312112ec29 upstream.

Rename the variable "tsrq" with "tccr_mask" as we are passing
TCCR mask to the ravb_wait() function.

There is no functional change.

Signed-off-by: Biju Das <biju.das.jz@...>
Suggested-by: Sergey Shtylyov <s.shtylyov@...>
Reviewed-by: Sergey Shtylyov <s.shtylyov@...>
Signed-off-by: Jakub Kicinski <kuba@...>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
---
drivers/net/ethernet/renesas/ravb.h | 2 +-
drivers/net/ethernet/renesas/ravb_main.c | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/renesas/ravb.h b/drivers/net/ethernet/renesas/ravb.h
index 527e865dee81..99d666a5fb49 100644
--- a/drivers/net/ethernet/renesas/ravb.h
+++ b/drivers/net/ethernet/renesas/ravb.h
@@ -1012,7 +1012,7 @@ struct ravb_hw_info {
netdev_features_t net_features;
int stats_len;
size_t max_rx_len;
- u32 tsrq;
+ u32 tccr_mask;
u32 rx_max_buf_size;
unsigned aligned_tx: 1;

diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
index 7225e6f70adc..ab57b72ea1cc 100644
--- a/drivers/net/ethernet/renesas/ravb_main.c
+++ b/drivers/net/ethernet/renesas/ravb_main.c
@@ -1019,7 +1019,7 @@ static int ravb_stop_dma(struct net_device *ndev)
int error;

/* Wait for stopping the hardware TX process */
- error = ravb_wait(ndev, TCCR, info->tsrq, 0);
+ error = ravb_wait(ndev, TCCR, info->tccr_mask, 0);

if (error)
return error;
@@ -2408,7 +2408,7 @@ static const struct ravb_hw_info ravb_gen3_hw_info = {
.net_features = NETIF_F_RXCSUM,
.stats_len = ARRAY_SIZE(ravb_gstrings_stats),
.max_rx_len = RX_BUF_SZ + RAVB_ALIGN - 1,
- .tsrq = TCCR_TSRQ0 | TCCR_TSRQ1 | TCCR_TSRQ2 | TCCR_TSRQ3,
+ .tccr_mask = TCCR_TSRQ0 | TCCR_TSRQ1 | TCCR_TSRQ2 | TCCR_TSRQ3,
.rx_max_buf_size = SZ_2K,
.internal_delay = 1,
.tx_counters = 1,
@@ -2433,7 +2433,7 @@ static const struct ravb_hw_info ravb_gen2_hw_info = {
.net_features = NETIF_F_RXCSUM,
.stats_len = ARRAY_SIZE(ravb_gstrings_stats),
.max_rx_len = RX_BUF_SZ + RAVB_ALIGN - 1,
- .tsrq = TCCR_TSRQ0 | TCCR_TSRQ1 | TCCR_TSRQ2 | TCCR_TSRQ3,
+ .tccr_mask = TCCR_TSRQ0 | TCCR_TSRQ1 | TCCR_TSRQ2 | TCCR_TSRQ3,
.rx_max_buf_size = SZ_2K,
.aligned_tx = 1,
.gptp = 1,
@@ -2454,7 +2454,7 @@ static const struct ravb_hw_info gbeth_hw_info = {
.gstrings_size = sizeof(ravb_gstrings_stats_gbeth),
.stats_len = ARRAY_SIZE(ravb_gstrings_stats_gbeth),
.max_rx_len = ALIGN(GBETH_RX_BUFF_MAX, RAVB_ALIGN),
- .tsrq = TCCR_TSRQ0,
+ .tccr_mask = TCCR_TSRQ0,
.rx_max_buf_size = SZ_8K,
.aligned_tx = 1,
.tx_counters = 1,
--
2.17.1


[PATCH 5.10.y-cip 52/61] ravb: Add support to retrieve stats for GbEthernet

Lad Prabhakar
 

From: Biju Das <biju.das.jz@...>

commit 0ee65bc14ff2f755c83b9261c510a70bf6ba8d60 upstream.

Add support for retrieving stats information for GbEthernet.

Signed-off-by: Biju Das <biju.das.jz@...>
Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
Reviewed-by: Sergey Shtylyov <s.shtylyov@...>
Signed-off-by: Jakub Kicinski <kuba@...>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
---
drivers/net/ethernet/renesas/ravb_main.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)

diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
index b874a6598dd7..7225e6f70adc 100644
--- a/drivers/net/ethernet/renesas/ravb_main.c
+++ b/drivers/net/ethernet/renesas/ravb_main.c
@@ -1491,6 +1491,24 @@ static void ravb_set_msglevel(struct net_device *ndev, u32 value)
priv->msg_enable = value;
}

+static const char ravb_gstrings_stats_gbeth[][ETH_GSTRING_LEN] = {
+ "rx_queue_0_current",
+ "tx_queue_0_current",
+ "rx_queue_0_dirty",
+ "tx_queue_0_dirty",
+ "rx_queue_0_packets",
+ "tx_queue_0_packets",
+ "rx_queue_0_bytes",
+ "tx_queue_0_bytes",
+ "rx_queue_0_mcast_packets",
+ "rx_queue_0_errors",
+ "rx_queue_0_crc_errors",
+ "rx_queue_0_frame_errors",
+ "rx_queue_0_length_errors",
+ "rx_queue_0_csum_offload_errors",
+ "rx_queue_0_over_errors",
+};
+
static const char ravb_gstrings_stats[][ETH_GSTRING_LEN] = {
"rx_queue_0_current",
"tx_queue_0_current",
@@ -2432,6 +2450,9 @@ static const struct ravb_hw_info gbeth_hw_info = {
.set_feature = ravb_set_features_gbeth,
.dmac_init = ravb_dmac_init_gbeth,
.emac_init = ravb_emac_init_gbeth,
+ .gstrings_stats = ravb_gstrings_stats_gbeth,
+ .gstrings_size = sizeof(ravb_gstrings_stats_gbeth),
+ .stats_len = ARRAY_SIZE(ravb_gstrings_stats_gbeth),
.max_rx_len = ALIGN(GBETH_RX_BUFF_MAX, RAVB_ALIGN),
.tsrq = TCCR_TSRQ0,
.rx_max_buf_size = SZ_8K,
--
2.17.1


[PATCH 5.10.y-cip 51/61] ravb: Add carrier_counters to struct ravb_hw_info

Lad Prabhakar
 

From: Biju Das <biju.das.jz@...>

commit b6a4ee6e74ded40bc261fee28f28a5df7021af3b upstream.

RZ/G2L E-MAC supports carrier counters.
Add a carrier_counter hw feature bit to struct ravb_hw_info
to add this feature only for RZ/G2L.

Signed-off-by: Biju Das <biju.das.jz@...>
Reviewed-by: Sergey Shtylyov <s.shtylyov@...>
Signed-off-by: Jakub Kicinski <kuba@...>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
---
drivers/net/ethernet/renesas/ravb.h | 3 +++
drivers/net/ethernet/renesas/ravb_main.c | 8 ++++++++
2 files changed, 11 insertions(+)

diff --git a/drivers/net/ethernet/renesas/ravb.h b/drivers/net/ethernet/renesas/ravb.h
index 99164318db26..527e865dee81 100644
--- a/drivers/net/ethernet/renesas/ravb.h
+++ b/drivers/net/ethernet/renesas/ravb.h
@@ -196,6 +196,8 @@ enum ravb_reg {
MAHR = 0x05c0,
MALR = 0x05c8,
TROCR = 0x0700, /* R-Car Gen3 and RZ/G2L only */
+ CXR41 = 0x0708, /* RZ/G2L only */
+ CXR42 = 0x0710, /* RZ/G2L only */
CEFCR = 0x0740,
FRECR = 0x0748,
TSFRCR = 0x0750,
@@ -1017,6 +1019,7 @@ struct ravb_hw_info {
/* hardware features */
unsigned internal_delay:1; /* AVB-DMAC has internal delays */
unsigned tx_counters:1; /* E-MAC has TX counters */
+ unsigned carrier_counters:1; /* E-MAC has carrier counters */
unsigned multi_irqs:1; /* AVB-DMAC and E-MAC has multiple irqs */
unsigned gptp:1; /* AVB-DMAC has gPTP support */
unsigned ccc_gac:1; /* AVB-DMAC has gPTP support active in config mode */
diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
index 2bfb903699cf..b874a6598dd7 100644
--- a/drivers/net/ethernet/renesas/ravb_main.c
+++ b/drivers/net/ethernet/renesas/ravb_main.c
@@ -2051,6 +2051,13 @@ static struct net_device_stats *ravb_get_stats(struct net_device *ndev)
ravb_write(ndev, 0, TROCR); /* (write clear) */
}

+ if (info->carrier_counters) {
+ nstats->collisions += ravb_read(ndev, CXR41);
+ ravb_write(ndev, 0, CXR41); /* (write clear) */
+ nstats->tx_carrier_errors += ravb_read(ndev, CXR42);
+ ravb_write(ndev, 0, CXR42); /* (write clear) */
+ }
+
nstats->rx_packets = stats0->rx_packets;
nstats->tx_packets = stats0->tx_packets;
nstats->rx_bytes = stats0->rx_bytes;
@@ -2430,6 +2437,7 @@ static const struct ravb_hw_info gbeth_hw_info = {
.rx_max_buf_size = SZ_8K,
.aligned_tx = 1,
.tx_counters = 1,
+ .carrier_counters = 1,
.half_duplex = 1,
};

--
2.17.1


[PATCH 5.10.y-cip 50/61] ravb: Fillup ravb_rx_gbeth() stub

Lad Prabhakar
 

From: Biju Das <biju.das.jz@...>

commit 1c59eb678cbd8d322d06d3a5514d36e8e1a4e84c upstream.

Fillup ravb_rx_gbeth() function to support RZ/G2L.

This patch also renames ravb_rcar_rx to ravb_rx_rcar to be
consistent with the naming convention used in sh_eth driver.

Signed-off-by: Biju Das <biju.das.jz@...>
Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
Reviewed-by: Sergey Shtylyov <s.shtylyov@...>
Signed-off-by: Jakub Kicinski <kuba@...>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
---
drivers/net/ethernet/renesas/ravb.h | 1 +
drivers/net/ethernet/renesas/ravb_main.c | 146 ++++++++++++++++++++++-
2 files changed, 142 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/renesas/ravb.h b/drivers/net/ethernet/renesas/ravb.h
index e9de3f8306ce..99164318db26 100644
--- a/drivers/net/ethernet/renesas/ravb.h
+++ b/drivers/net/ethernet/renesas/ravb.h
@@ -1043,6 +1043,7 @@ struct ravb_private {
struct ravb_ex_rx_desc *rx_ring[NUM_RX_QUEUE];
struct ravb_tx_desc *tx_ring[NUM_TX_QUEUE];
void *tx_align[NUM_TX_QUEUE];
+ struct sk_buff *rx_1st_skb;
struct sk_buff **rx_skb[NUM_RX_QUEUE];
struct sk_buff **tx_skb[NUM_TX_QUEUE];
u32 rx_over_errors;
diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
index 2412b570e1a1..2bfb903699cf 100644
--- a/drivers/net/ethernet/renesas/ravb_main.c
+++ b/drivers/net/ethernet/renesas/ravb_main.c
@@ -732,15 +732,151 @@ static void ravb_rx_csum(struct sk_buff *skb)
skb_trim(skb, skb->len - sizeof(__sum16));
}

+static struct sk_buff *ravb_get_skb_gbeth(struct net_device *ndev, int entry,
+ struct ravb_rx_desc *desc)
+{
+ struct ravb_private *priv = netdev_priv(ndev);
+ struct sk_buff *skb;
+
+ skb = priv->rx_skb[RAVB_BE][entry];
+ priv->rx_skb[RAVB_BE][entry] = NULL;
+ dma_unmap_single(ndev->dev.parent, le32_to_cpu(desc->dptr),
+ ALIGN(GBETH_RX_BUFF_MAX, 16), DMA_FROM_DEVICE);
+
+ return skb;
+}
+
/* Packet receive function for Gigabit Ethernet */
static bool ravb_rx_gbeth(struct net_device *ndev, int *quota, int q)
{
- /* Place holder */
- return true;
+ struct ravb_private *priv = netdev_priv(ndev);
+ const struct ravb_hw_info *info = priv->info;
+ struct net_device_stats *stats;
+ struct ravb_rx_desc *desc;
+ struct sk_buff *skb;
+ dma_addr_t dma_addr;
+ u8 desc_status;
+ int boguscnt;
+ u16 pkt_len;
+ u8 die_dt;
+ int entry;
+ int limit;
+
+ entry = priv->cur_rx[q] % priv->num_rx_ring[q];
+ boguscnt = priv->dirty_rx[q] + priv->num_rx_ring[q] - priv->cur_rx[q];
+ stats = &priv->stats[q];
+
+ boguscnt = min(boguscnt, *quota);
+ limit = boguscnt;
+ desc = &priv->gbeth_rx_ring[entry];
+ while (desc->die_dt != DT_FEMPTY) {
+ /* Descriptor type must be checked before all other reads */
+ dma_rmb();
+ desc_status = desc->msc;
+ pkt_len = le16_to_cpu(desc->ds_cc) & RX_DS;
+
+ if (--boguscnt < 0)
+ break;
+
+ /* We use 0-byte descriptors to mark the DMA mapping errors */
+ if (!pkt_len)
+ continue;
+
+ if (desc_status & MSC_MC)
+ stats->multicast++;
+
+ if (desc_status & (MSC_CRC | MSC_RFE | MSC_RTSF | MSC_RTLF | MSC_CEEF)) {
+ stats->rx_errors++;
+ if (desc_status & MSC_CRC)
+ stats->rx_crc_errors++;
+ if (desc_status & MSC_RFE)
+ stats->rx_frame_errors++;
+ if (desc_status & (MSC_RTLF | MSC_RTSF))
+ stats->rx_length_errors++;
+ if (desc_status & MSC_CEEF)
+ stats->rx_missed_errors++;
+ } else {
+ die_dt = desc->die_dt & 0xF0;
+ switch (die_dt) {
+ case DT_FSINGLE:
+ skb = ravb_get_skb_gbeth(ndev, entry, desc);
+ skb_put(skb, pkt_len);
+ skb->protocol = eth_type_trans(skb, ndev);
+ napi_gro_receive(&priv->napi[q], skb);
+ stats->rx_packets++;
+ stats->rx_bytes += pkt_len;
+ break;
+ case DT_FSTART:
+ priv->rx_1st_skb = ravb_get_skb_gbeth(ndev, entry, desc);
+ skb_put(priv->rx_1st_skb, pkt_len);
+ break;
+ case DT_FMID:
+ skb = ravb_get_skb_gbeth(ndev, entry, desc);
+ skb_copy_to_linear_data_offset(priv->rx_1st_skb,
+ priv->rx_1st_skb->len,
+ skb->data,
+ pkt_len);
+ skb_put(priv->rx_1st_skb, pkt_len);
+ dev_kfree_skb(skb);
+ break;
+ case DT_FEND:
+ skb = ravb_get_skb_gbeth(ndev, entry, desc);
+ skb_copy_to_linear_data_offset(priv->rx_1st_skb,
+ priv->rx_1st_skb->len,
+ skb->data,
+ pkt_len);
+ skb_put(priv->rx_1st_skb, pkt_len);
+ dev_kfree_skb(skb);
+ priv->rx_1st_skb->protocol =
+ eth_type_trans(priv->rx_1st_skb, ndev);
+ napi_gro_receive(&priv->napi[q],
+ priv->rx_1st_skb);
+ stats->rx_packets++;
+ stats->rx_bytes += priv->rx_1st_skb->len;
+ break;
+ }
+ }
+
+ entry = (++priv->cur_rx[q]) % priv->num_rx_ring[q];
+ desc = &priv->gbeth_rx_ring[entry];
+ }
+
+ /* Refill the RX ring buffers. */
+ for (; priv->cur_rx[q] - priv->dirty_rx[q] > 0; priv->dirty_rx[q]++) {
+ entry = priv->dirty_rx[q] % priv->num_rx_ring[q];
+ desc = &priv->gbeth_rx_ring[entry];
+ desc->ds_cc = cpu_to_le16(GBETH_RX_DESC_DATA_SIZE);
+
+ if (!priv->rx_skb[q][entry]) {
+ skb = netdev_alloc_skb(ndev, info->max_rx_len);
+ if (!skb)
+ break;
+ ravb_set_buffer_align(skb);
+ dma_addr = dma_map_single(ndev->dev.parent,
+ skb->data,
+ GBETH_RX_BUFF_MAX,
+ DMA_FROM_DEVICE);
+ skb_checksum_none_assert(skb);
+ /* We just set the data size to 0 for a failed mapping
+ * which should prevent DMA from happening...
+ */
+ if (dma_mapping_error(ndev->dev.parent, dma_addr))
+ desc->ds_cc = cpu_to_le16(0);
+ desc->dptr = cpu_to_le32(dma_addr);
+ priv->rx_skb[q][entry] = skb;
+ }
+ /* Descriptor type must be set after all the above writes */
+ dma_wmb();
+ desc->die_dt = DT_FEMPTY;
+ }
+
+ *quota -= limit - (++boguscnt);
+
+ return boguscnt <= 0;
}

/* Packet receive function for Ethernet AVB */
-static bool ravb_rcar_rx(struct net_device *ndev, int *quota, int q)
+static bool ravb_rx_rcar(struct net_device *ndev, int *quota, int q)
{
struct ravb_private *priv = netdev_priv(ndev);
const struct ravb_hw_info *info = priv->info;
@@ -2236,7 +2372,7 @@ static const struct ravb_hw_info ravb_gen3_hw_info = {
.rx_ring_free = ravb_rx_ring_free_rcar,
.rx_ring_format = ravb_rx_ring_format_rcar,
.alloc_rx_desc = ravb_alloc_rx_desc_rcar,
- .receive = ravb_rcar_rx,
+ .receive = ravb_rx_rcar,
.set_rate = ravb_set_rate_rcar,
.set_feature = ravb_set_features_rcar,
.dmac_init = ravb_dmac_init_rcar,
@@ -2261,7 +2397,7 @@ static const struct ravb_hw_info ravb_gen2_hw_info = {
.rx_ring_free = ravb_rx_ring_free_rcar,
.rx_ring_format = ravb_rx_ring_format_rcar,
.alloc_rx_desc = ravb_alloc_rx_desc_rcar,
- .receive = ravb_rcar_rx,
+ .receive = ravb_rx_rcar,
.set_rate = ravb_set_rate_rcar,
.set_feature = ravb_set_features_rcar,
.dmac_init = ravb_dmac_init_rcar,
--
2.17.1


[PATCH 5.10.y-cip 49/61] ravb: Fillup ravb_rx_ring_format_gbeth() stub

Lad Prabhakar
 

From: Biju Das <biju.das.jz@...>

commit 16a6e245a9f3cd661f3824940bb62b0ab4503d53 upstream.

Fillup ravb_rx_ring_format_gbeth() function to support RZ/G2L.

This patch also renames ravb_rx_ring_format to ravb_rx_ring_format_rcar
to be consistent with the naming convention used in sh_eth driver.

Signed-off-by: Biju Das <biju.das.jz@...>
Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
Reviewed-by: Sergey Shtylyov <s.shtylyov@...>
Signed-off-by: Jakub Kicinski <kuba@...>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
---
drivers/net/ethernet/renesas/ravb.h | 1 +
drivers/net/ethernet/renesas/ravb_main.c | 34 +++++++++++++++++++++---
2 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/renesas/ravb.h b/drivers/net/ethernet/renesas/ravb.h
index ed771ead61b9..e9de3f8306ce 100644
--- a/drivers/net/ethernet/renesas/ravb.h
+++ b/drivers/net/ethernet/renesas/ravb.h
@@ -970,6 +970,7 @@ enum CXR31_BIT {
#define RX_BUF_SZ (2048 - ETH_FCS_LEN + sizeof(__sum16))

#define GBETH_RX_BUFF_MAX 8192
+#define GBETH_RX_DESC_DATA_SIZE 4080

struct ravb_tstamp_skb {
struct list_head list;
diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
index 6f9065212791..2412b570e1a1 100644
--- a/drivers/net/ethernet/renesas/ravb_main.c
+++ b/drivers/net/ethernet/renesas/ravb_main.c
@@ -325,10 +325,36 @@ static void ravb_ring_free(struct net_device *ndev, int q)

static void ravb_rx_ring_format_gbeth(struct net_device *ndev, int q)
{
- /* Place holder */
+ struct ravb_private *priv = netdev_priv(ndev);
+ struct ravb_rx_desc *rx_desc;
+ unsigned int rx_ring_size;
+ dma_addr_t dma_addr;
+ unsigned int i;
+
+ rx_ring_size = sizeof(*rx_desc) * priv->num_rx_ring[q];
+ memset(priv->gbeth_rx_ring, 0, rx_ring_size);
+ /* Build RX ring buffer */
+ for (i = 0; i < priv->num_rx_ring[q]; i++) {
+ /* RX descriptor */
+ rx_desc = &priv->gbeth_rx_ring[i];
+ rx_desc->ds_cc = cpu_to_le16(GBETH_RX_DESC_DATA_SIZE);
+ dma_addr = dma_map_single(ndev->dev.parent, priv->rx_skb[q][i]->data,
+ GBETH_RX_BUFF_MAX,
+ DMA_FROM_DEVICE);
+ /* We just set the data size to 0 for a failed mapping which
+ * should prevent DMA from happening...
+ */
+ if (dma_mapping_error(ndev->dev.parent, dma_addr))
+ rx_desc->ds_cc = cpu_to_le16(0);
+ rx_desc->dptr = cpu_to_le32(dma_addr);
+ rx_desc->die_dt = DT_FEMPTY;
+ }
+ rx_desc = &priv->gbeth_rx_ring[i];
+ rx_desc->dptr = cpu_to_le32((u32)priv->rx_desc_dma[q]);
+ rx_desc->die_dt = DT_LINKFIX; /* type */
}

-static void ravb_rx_ring_format(struct net_device *ndev, int q)
+static void ravb_rx_ring_format_rcar(struct net_device *ndev, int q)
{
struct ravb_private *priv = netdev_priv(ndev);
struct ravb_ex_rx_desc *rx_desc;
@@ -2208,7 +2234,7 @@ static int ravb_mdio_release(struct ravb_private *priv)

static const struct ravb_hw_info ravb_gen3_hw_info = {
.rx_ring_free = ravb_rx_ring_free_rcar,
- .rx_ring_format = ravb_rx_ring_format,
+ .rx_ring_format = ravb_rx_ring_format_rcar,
.alloc_rx_desc = ravb_alloc_rx_desc_rcar,
.receive = ravb_rcar_rx,
.set_rate = ravb_set_rate_rcar,
@@ -2233,7 +2259,7 @@ static const struct ravb_hw_info ravb_gen3_hw_info = {

static const struct ravb_hw_info ravb_gen2_hw_info = {
.rx_ring_free = ravb_rx_ring_free_rcar,
- .rx_ring_format = ravb_rx_ring_format,
+ .rx_ring_format = ravb_rx_ring_format_rcar,
.alloc_rx_desc = ravb_alloc_rx_desc_rcar,
.receive = ravb_rcar_rx,
.set_rate = ravb_set_rate_rcar,
--
2.17.1


[PATCH 5.10.y-cip 48/61] ravb: Fillup ravb_rx_ring_free_gbeth() stub

Lad Prabhakar
 

From: Biju Das <biju.das.jz@...>

commit 2458b8edb887108b8a6aae567b01e5e2a73bd8d8 upstream.

Fillup ravb_rx_ring_free_gbeth() function to support RZ/G2L.

This patch also renames ravb_rx_ring_free to ravb_rx_ring_free_rcar
to be consistent with the naming convention used in sh_eth driver.

Signed-off-by: Biju Das <biju.das.jz@...>
Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
Reviewed-by: Sergey Shtylyov <s.shtylyov@...>
Signed-off-by: Jakub Kicinski <kuba@...>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@...>
---
drivers/net/ethernet/renesas/ravb_main.c | 28 ++++++++++++++++++++----
1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
index 02e8a7761822..6f9065212791 100644
--- a/drivers/net/ethernet/renesas/ravb_main.c
+++ b/drivers/net/ethernet/renesas/ravb_main.c
@@ -234,10 +234,30 @@ static int ravb_tx_free(struct net_device *ndev, int q, bool free_txed_only)

static void ravb_rx_ring_free_gbeth(struct net_device *ndev, int q)
{
- /* Place holder */
+ struct ravb_private *priv = netdev_priv(ndev);
+ unsigned int ring_size;
+ unsigned int i;
+
+ if (!priv->gbeth_rx_ring)
+ return;
+
+ for (i = 0; i < priv->num_rx_ring[q]; i++) {
+ struct ravb_rx_desc *desc = &priv->gbeth_rx_ring[i];
+
+ if (!dma_mapping_error(ndev->dev.parent,
+ le32_to_cpu(desc->dptr)))
+ dma_unmap_single(ndev->dev.parent,
+ le32_to_cpu(desc->dptr),
+ GBETH_RX_BUFF_MAX,
+ DMA_FROM_DEVICE);
+ }
+ ring_size = sizeof(struct ravb_rx_desc) * (priv->num_rx_ring[q] + 1);
+ dma_free_coherent(ndev->dev.parent, ring_size, priv->gbeth_rx_ring,
+ priv->rx_desc_dma[q]);
+ priv->gbeth_rx_ring = NULL;
}

-static void ravb_rx_ring_free(struct net_device *ndev, int q)
+static void ravb_rx_ring_free_rcar(struct net_device *ndev, int q)
{
struct ravb_private *priv = netdev_priv(ndev);
unsigned int ring_size;
@@ -2187,7 +2207,7 @@ static int ravb_mdio_release(struct ravb_private *priv)
}

static const struct ravb_hw_info ravb_gen3_hw_info = {
- .rx_ring_free = ravb_rx_ring_free,
+ .rx_ring_free = ravb_rx_ring_free_rcar,
.rx_ring_format = ravb_rx_ring_format,
.alloc_rx_desc = ravb_alloc_rx_desc_rcar,
.receive = ravb_rcar_rx,
@@ -2212,7 +2232,7 @@ static const struct ravb_hw_info ravb_gen3_hw_info = {
};

static const struct ravb_hw_info ravb_gen2_hw_info = {
- .rx_ring_free = ravb_rx_ring_free,
+ .rx_ring_free = ravb_rx_ring_free_rcar,
.rx_ring_format = ravb_rx_ring_format,
.alloc_rx_desc = ravb_alloc_rx_desc_rcar,
.receive = ravb_rcar_rx,
--
2.17.1

2141 - 2160 of 9570