Skip to content

Commit a6155fd

Browse files
LKomaryanskiylorc
authored andcommitted
net: renesas: rswitch: add sysfs attribute to enable/disable L3 offload
For some testing scenarios, we need to disable L3 offload. This patch implements enabling/disabling L3 offload via sysfs attribute for platform R-Switch device. By default, L3 offload is enabled, but in case you need to disable it, write 0 to the appropriate sysfs file. e.g for S4 it placed in /sys/devices/platform/soc/e68c0000.ethernet/l3_offload Reviewed-by: Dmytro Firsov <[email protected]> Acked-by: Volodymyr Babchuk <[email protected]> Signed-off-by: Leonid Komarianskyi <[email protected]>
1 parent 7c6ca16 commit a6155fd

File tree

2 files changed

+58
-1
lines changed

2 files changed

+58
-1
lines changed

drivers/net/ethernet/renesas/rswitch.c

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -943,6 +943,7 @@ struct rswitch_ipv4_route {
943943
u32 ip;
944944
u32 subnet;
945945
u32 mask;
946+
struct fib_nh *nh;
946947
struct rswitch_device *dev;
947948
struct list_head param_list;
948949
struct list_head list;
@@ -1180,7 +1181,7 @@ static bool rswitch_rx_chain(struct net_device *ndev, int *quota, struct rswitch
11801181
skb->dev = ndev;
11811182
}
11821183

1183-
if (learn_chain) {
1184+
if (learn_chain && rdev->priv->offload_enabled) {
11841185
struct rswitch_private *priv = rdev->priv;
11851186
struct iphdr *iphdr;
11861187
struct ethhdr *ethhdr;
@@ -2742,6 +2743,7 @@ static void rswitch_fib_event_add(struct rswitch_fib_event_work *fib_work)
27422743

27432744
if (!rswitch_add_ipv4_dst_route(new_routing_list, dev, be32_to_cpu(nh->nh_saddr)))
27442745
nh->fib_nh_flags |= RTNH_F_OFFLOAD;
2746+
new_routing_list->nh = nh;
27452747
}
27462748

27472749
static void rswitch_fib_event_remove(struct rswitch_fib_event_work *fib_work)
@@ -4123,6 +4125,7 @@ static void cleanup_all_routes(struct rswitch_device *rdev)
41234125
mutex_lock(&rdev->priv->ipv4_forward_lock);
41244126
list_for_each_safe(cur, tmp, &rdev->routing_list) {
41254127
routing_list = list_entry(cur, struct rswitch_ipv4_route, list);
4128+
routing_list->nh->fib_nh_flags &= ~RTNH_F_OFFLOAD;
41264129
list_for_each_safe(cur_param_list, tmp_param_list, &routing_list->param_list) {
41274130
param_list =
41284131
list_entry(cur_param_list, struct l3_ipv4_fwd_param_list, list);
@@ -4238,6 +4241,47 @@ static struct notifier_block netevent_notifier = {
42384241
.notifier_call = rswitch_netevent_cb,
42394242
};
42404243

4244+
static ssize_t l3_offload_show(struct device *dev, struct device_attribute *attr,
4245+
char *buf)
4246+
{
4247+
return sysfs_emit(buf, "%d\n", glob_priv->offload_enabled);
4248+
}
4249+
4250+
static void rswitch_disable_offload(struct rswitch_private *priv)
4251+
{
4252+
struct rswitch_device *rdev;
4253+
4254+
read_lock(&priv->rdev_list_lock);
4255+
list_for_each_entry(rdev, &priv->rdev_list, list)
4256+
cleanup_all_routes(rdev);
4257+
read_unlock(&priv->rdev_list_lock);
4258+
}
4259+
4260+
static ssize_t l3_offload_store(struct device *dev, struct device_attribute *attr,
4261+
const char *buf, size_t count)
4262+
{
4263+
long new_value;
4264+
4265+
if (kstrtol(buf, 10, &new_value))
4266+
return -EINVAL;
4267+
4268+
new_value = !!new_value;
4269+
if (new_value != glob_priv->offload_enabled) {
4270+
if (new_value) {
4271+
register_fib_notifier(&init_net, &glob_priv->fib_nb, NULL, NULL);
4272+
} else {
4273+
unregister_fib_notifier(&init_net, &glob_priv->fib_nb);
4274+
rswitch_disable_offload(glob_priv);
4275+
}
4276+
4277+
glob_priv->offload_enabled = new_value;
4278+
}
4279+
4280+
return count;
4281+
}
4282+
4283+
static DEVICE_ATTR_RW(l3_offload);
4284+
42414285
static int renesas_eth_sw_probe(struct platform_device *pdev)
42424286
{
42434287
struct rswitch_private *priv;
@@ -4357,10 +4401,21 @@ static int renesas_eth_sw_probe(struct platform_device *pdev)
43574401
ret = register_fib_notifier(&init_net, &priv->fib_nb, NULL, NULL);
43584402
if (ret)
43594403
goto unregister_netevent_notifier;
4404+
4405+
priv->offload_enabled = true;
4406+
ret = device_create_file(&pdev->dev, &dev_attr_l3_offload);
4407+
if (ret) {
4408+
dev_err(&priv->pdev->dev, "failed to register offload attribute, ret=%d\n",
4409+
ret);
4410+
goto unregister_fib_notifier;
4411+
}
43604412
}
43614413

43624414
return 0;
43634415

4416+
unregister_fib_notifier:
4417+
unregister_fib_notifier(&init_net, &priv->fib_nb);
4418+
43644419
unregister_netevent_notifier:
43654420
unregister_netevent_notifier(&netevent_notifier);
43664421

@@ -4389,6 +4444,7 @@ static int renesas_eth_sw_remove(struct platform_device *pdev)
43894444
struct rswitch_private *priv = platform_get_drvdata(pdev);
43904445

43914446
if (!parallel_mode) {
4447+
device_remove_file(&pdev->dev, &dev_attr_l3_offload);
43924448
unregister_fib_notifier(&init_net, &priv->fib_nb);
43934449
destroy_workqueue(priv->rswitch_fib_wq);
43944450
unregister_netevent_notifier(&netevent_notifier);

drivers/net/ethernet/renesas/rswitch.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ struct rswitch_private {
287287
struct workqueue_struct *rswitch_netevent_wq;
288288

289289
bool ipv4_forward_enabled;
290+
bool offload_enabled;
290291
struct mutex ipv4_forward_lock;
291292
struct workqueue_struct *rswitch_forward_wq;
292293
};

0 commit comments

Comments
 (0)