blob: 7cc4553c082b76a169b12d00bcd755ea15140a3f [file] [log] [blame]
developere5e687d2023-08-08 16:05:33 +08001// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright (c) 2023 MediaTek Inc. All Rights Reserved.
4 *
5 * Author: Ren-Ting Wang <ren-ting.wang@mediatek.com>
6 */
7
8#include <linux/device.h>
9#include <linux/hashtable.h>
10#include <linux/netdevice.h>
11#include <linux/netfilter.h>
12#include <linux/netfilter_ipv4.h>
13#include <linux/notifier.h>
14#include <net/arp.h>
15#include <net/flow.h>
16#include <net/ip.h>
17#include <net/ip_tunnels.h>
18#include <net/netevent.h>
19#include <net/net_namespace.h>
20#include <net/neighbour.h>
21#include <net/route.h>
22
23#include "internal.h"
24#include "netsys.h"
25#include "net-event.h"
26#include "mcu.h"
27#include "ser.h"
28#include "trm.h"
29#include "tunnel.h"
30
31static struct completion wait_fe_reset_done;
32
33static void mtk_tops_netdev_ser_callback(struct tops_ser_params *ser_param)
34{
35 struct net_device *netdev = ser_param->data.net.ndev;
36
37 WARN_ON(ser_param->type != TOPS_SER_NETSYS_FE_RST);
38
39 mtk_trm_dump(TRM_RSN_FE_RESET);
40
41 /* send tops dump done notification to mtk eth */
42 rtnl_lock();
43 call_netdevice_notifiers(MTK_TOPS_DUMP_DONE, netdev);
44 rtnl_unlock();
45
46 /* wait for FE reset done notification */
47 /* TODO : if not received FE reset done notification */
48 wait_for_completion(&wait_fe_reset_done);
49}
50
51static inline void mtk_tops_netdev_ser(struct net_device *dev)
52{
53 struct tops_ser_params ser_params = {
54 .type = TOPS_SER_NETSYS_FE_RST,
55 .data.net.ndev = dev,
56 .ser_callback = mtk_tops_netdev_ser_callback,
57 };
58
59 mtk_tops_ser(&ser_params);
60}
61
62/* TODO: update tunnel status when user delete or change tunnel parameters */
63/*
64 * eth will send out MTK_FE_START_RESET event if detected wdma abnormal, or
65 * send out MTK_FE_STOP_TRAFFIC event if detected qdma or adma or tdma abnormal,
66 * then do FE reset, so we use the same mcu event to represent it.
67 *
68 * after FE reset done, eth will send out MTK_FE_START_TRAFFIC event if this is
69 * wdma abnormal induced FE reset, or send out MTK_FE_RESET_DONE event for qdma
70 * or adma or tdma abnormal induced FE reset.
71 */
72static int mtk_tops_netdev_callback(struct notifier_block *nb,
73 unsigned long event,
74 void *data)
75{
76 struct net_device *dev = netdev_notifier_info_to_dev(data);
77 int ret = 0;
78
79 switch (event) {
80 case NETDEV_UP:
81 break;
82 case NETDEV_DOWN:
83 mtk_tops_tnl_offload_netdev_down(dev);
84 break;
85 case MTK_FE_START_RESET:
86 case MTK_FE_STOP_TRAFFIC:
87 mtk_tops_netdev_ser(dev);
88 break;
89 case MTK_FE_RESET_DONE:
90 case MTK_FE_START_TRAFFIC:
91 complete(&wait_fe_reset_done);
92 break;
93 default:
94 break;
95 }
96
97 return ret;
98}
99
100static struct notifier_block mtk_tops_netdev_notifier = {
101 .notifier_call = mtk_tops_netdev_callback,
102};
103
104static int mtk_tops_netevent_callback(struct notifier_block *nb,
105 unsigned long event,
106 void *data)
107{
108 int ret = 0;
109
110 switch (event) {
111 case NETEVENT_NEIGH_UPDATE:
112 break;
113 default:
114 break;
115 }
116
117 return ret;
118}
119
120static struct notifier_block mtk_tops_netevent_notifier = {
121 .notifier_call = mtk_tops_netevent_callback,
122};
123
124int mtk_tops_netevent_register(struct platform_device *pdev)
125{
126 int ret = 0;
127
128 ret = register_netdevice_notifier(&mtk_tops_netdev_notifier);
129 if (ret) {
130 TOPS_ERR("TOPS register netdev notifier failed: %d\n", ret);
131 return ret;
132 }
133
134 ret = register_netevent_notifier(&mtk_tops_netevent_notifier);
135 if (ret) {
136 unregister_netdevice_notifier(&mtk_tops_netdev_notifier);
137 TOPS_ERR("TOPS register net event notifier failed: %d\n", ret);
138 return ret;
139 }
140
141 init_completion(&wait_fe_reset_done);
142
143 return ret;
144}
145
146void mtk_tops_netevent_unregister(struct platform_device *pdev)
147{
148 unregister_netevent_notifier(&mtk_tops_netevent_notifier);
149
150 unregister_netdevice_notifier(&mtk_tops_netdev_notifier);
151}