Merge tag '5.10-rc-smb3-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6
[linux-2.6-microblaze.git] / drivers / net / netdevsim / dev.c
1 /*
2  * Copyright (c) 2018 Cumulus Networks. All rights reserved.
3  * Copyright (c) 2018 David Ahern <dsa@cumulusnetworks.com>
4  * Copyright (c) 2019 Mellanox Technologies. All rights reserved.
5  *
6  * This software is licensed under the GNU General License Version 2,
7  * June 1991 as shown in the file COPYING in the top-level directory of this
8  * source tree.
9  *
10  * THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS"
11  * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
12  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
13  * FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
14  * OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME
15  * THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16  */
17
18 #include <linux/debugfs.h>
19 #include <linux/device.h>
20 #include <linux/etherdevice.h>
21 #include <linux/inet.h>
22 #include <linux/jiffies.h>
23 #include <linux/kernel.h>
24 #include <linux/list.h>
25 #include <linux/mutex.h>
26 #include <linux/random.h>
27 #include <linux/rtnetlink.h>
28 #include <linux/workqueue.h>
29 #include <net/devlink.h>
30 #include <net/ip.h>
31 #include <net/flow_offload.h>
32 #include <uapi/linux/devlink.h>
33 #include <uapi/linux/ip.h>
34 #include <uapi/linux/udp.h>
35
36 #include "netdevsim.h"
37
38 static struct dentry *nsim_dev_ddir;
39
40 #define NSIM_DEV_DUMMY_REGION_SIZE (1024 * 32)
41
42 static int
43 nsim_dev_take_snapshot(struct devlink *devlink,
44                        const struct devlink_region_ops *ops,
45                        struct netlink_ext_ack *extack,
46                        u8 **data)
47 {
48         void *dummy_data;
49
50         dummy_data = kmalloc(NSIM_DEV_DUMMY_REGION_SIZE, GFP_KERNEL);
51         if (!dummy_data)
52                 return -ENOMEM;
53
54         get_random_bytes(dummy_data, NSIM_DEV_DUMMY_REGION_SIZE);
55
56         *data = dummy_data;
57
58         return 0;
59 }
60
61 static ssize_t nsim_dev_take_snapshot_write(struct file *file,
62                                             const char __user *data,
63                                             size_t count, loff_t *ppos)
64 {
65         struct nsim_dev *nsim_dev = file->private_data;
66         struct devlink *devlink;
67         u8 *dummy_data;
68         int err;
69         u32 id;
70
71         devlink = priv_to_devlink(nsim_dev);
72
73         err = nsim_dev_take_snapshot(devlink, NULL, NULL, &dummy_data);
74         if (err)
75                 return err;
76
77         err = devlink_region_snapshot_id_get(devlink, &id);
78         if (err) {
79                 pr_err("Failed to get snapshot id\n");
80                 kfree(dummy_data);
81                 return err;
82         }
83         err = devlink_region_snapshot_create(nsim_dev->dummy_region,
84                                              dummy_data, id);
85         devlink_region_snapshot_id_put(devlink, id);
86         if (err) {
87                 pr_err("Failed to create region snapshot\n");
88                 kfree(dummy_data);
89                 return err;
90         }
91
92         return count;
93 }
94
95 static const struct file_operations nsim_dev_take_snapshot_fops = {
96         .open = simple_open,
97         .write = nsim_dev_take_snapshot_write,
98         .llseek = generic_file_llseek,
99 };
100
101 static ssize_t nsim_dev_trap_fa_cookie_read(struct file *file,
102                                             char __user *data,
103                                             size_t count, loff_t *ppos)
104 {
105         struct nsim_dev *nsim_dev = file->private_data;
106         struct flow_action_cookie *fa_cookie;
107         unsigned int buf_len;
108         ssize_t ret;
109         char *buf;
110
111         spin_lock(&nsim_dev->fa_cookie_lock);
112         fa_cookie = nsim_dev->fa_cookie;
113         if (!fa_cookie) {
114                 ret = -EINVAL;
115                 goto errout;
116         }
117         buf_len = fa_cookie->cookie_len * 2;
118         buf = kmalloc(buf_len, GFP_ATOMIC);
119         if (!buf) {
120                 ret = -ENOMEM;
121                 goto errout;
122         }
123         bin2hex(buf, fa_cookie->cookie, fa_cookie->cookie_len);
124         spin_unlock(&nsim_dev->fa_cookie_lock);
125
126         ret = simple_read_from_buffer(data, count, ppos, buf, buf_len);
127
128         kfree(buf);
129         return ret;
130
131 errout:
132         spin_unlock(&nsim_dev->fa_cookie_lock);
133         return ret;
134 }
135
136 static ssize_t nsim_dev_trap_fa_cookie_write(struct file *file,
137                                              const char __user *data,
138                                              size_t count, loff_t *ppos)
139 {
140         struct nsim_dev *nsim_dev = file->private_data;
141         struct flow_action_cookie *fa_cookie;
142         size_t cookie_len;
143         ssize_t ret;
144         char *buf;
145
146         if (*ppos != 0)
147                 return -EINVAL;
148         cookie_len = (count - 1) / 2;
149         if ((count - 1) % 2)
150                 return -EINVAL;
151         buf = kmalloc(count, GFP_KERNEL | __GFP_NOWARN);
152         if (!buf)
153                 return -ENOMEM;
154
155         ret = simple_write_to_buffer(buf, count, ppos, data, count);
156         if (ret < 0)
157                 goto free_buf;
158
159         fa_cookie = kmalloc(sizeof(*fa_cookie) + cookie_len,
160                             GFP_KERNEL | __GFP_NOWARN);
161         if (!fa_cookie) {
162                 ret = -ENOMEM;
163                 goto free_buf;
164         }
165
166         fa_cookie->cookie_len = cookie_len;
167         ret = hex2bin(fa_cookie->cookie, buf, cookie_len);
168         if (ret)
169                 goto free_fa_cookie;
170         kfree(buf);
171
172         spin_lock(&nsim_dev->fa_cookie_lock);
173         kfree(nsim_dev->fa_cookie);
174         nsim_dev->fa_cookie = fa_cookie;
175         spin_unlock(&nsim_dev->fa_cookie_lock);
176
177         return count;
178
179 free_fa_cookie:
180         kfree(fa_cookie);
181 free_buf:
182         kfree(buf);
183         return ret;
184 }
185
186 static const struct file_operations nsim_dev_trap_fa_cookie_fops = {
187         .open = simple_open,
188         .read = nsim_dev_trap_fa_cookie_read,
189         .write = nsim_dev_trap_fa_cookie_write,
190         .llseek = generic_file_llseek,
191 };
192
193 static int nsim_dev_debugfs_init(struct nsim_dev *nsim_dev)
194 {
195         char dev_ddir_name[sizeof(DRV_NAME) + 10];
196
197         sprintf(dev_ddir_name, DRV_NAME "%u", nsim_dev->nsim_bus_dev->dev.id);
198         nsim_dev->ddir = debugfs_create_dir(dev_ddir_name, nsim_dev_ddir);
199         if (IS_ERR(nsim_dev->ddir))
200                 return PTR_ERR(nsim_dev->ddir);
201         nsim_dev->ports_ddir = debugfs_create_dir("ports", nsim_dev->ddir);
202         if (IS_ERR(nsim_dev->ports_ddir))
203                 return PTR_ERR(nsim_dev->ports_ddir);
204         debugfs_create_bool("fw_update_status", 0600, nsim_dev->ddir,
205                             &nsim_dev->fw_update_status);
206         debugfs_create_u32("fw_update_overwrite_mask", 0600, nsim_dev->ddir,
207                             &nsim_dev->fw_update_overwrite_mask);
208         debugfs_create_u32("max_macs", 0600, nsim_dev->ddir,
209                            &nsim_dev->max_macs);
210         debugfs_create_bool("test1", 0600, nsim_dev->ddir,
211                             &nsim_dev->test1);
212         nsim_dev->take_snapshot = debugfs_create_file("take_snapshot",
213                                                       0200,
214                                                       nsim_dev->ddir,
215                                                       nsim_dev,
216                                                 &nsim_dev_take_snapshot_fops);
217         debugfs_create_bool("dont_allow_reload", 0600, nsim_dev->ddir,
218                             &nsim_dev->dont_allow_reload);
219         debugfs_create_bool("fail_reload", 0600, nsim_dev->ddir,
220                             &nsim_dev->fail_reload);
221         debugfs_create_file("trap_flow_action_cookie", 0600, nsim_dev->ddir,
222                             nsim_dev, &nsim_dev_trap_fa_cookie_fops);
223         debugfs_create_bool("fail_trap_group_set", 0600,
224                             nsim_dev->ddir,
225                             &nsim_dev->fail_trap_group_set);
226         debugfs_create_bool("fail_trap_policer_set", 0600,
227                             nsim_dev->ddir,
228                             &nsim_dev->fail_trap_policer_set);
229         debugfs_create_bool("fail_trap_policer_counter_get", 0600,
230                             nsim_dev->ddir,
231                             &nsim_dev->fail_trap_policer_counter_get);
232         nsim_udp_tunnels_debugfs_create(nsim_dev);
233         return 0;
234 }
235
236 static void nsim_dev_debugfs_exit(struct nsim_dev *nsim_dev)
237 {
238         debugfs_remove_recursive(nsim_dev->ports_ddir);
239         debugfs_remove_recursive(nsim_dev->ddir);
240 }
241
242 static int nsim_dev_port_debugfs_init(struct nsim_dev *nsim_dev,
243                                       struct nsim_dev_port *nsim_dev_port)
244 {
245         char port_ddir_name[16];
246         char dev_link_name[32];
247
248         sprintf(port_ddir_name, "%u", nsim_dev_port->port_index);
249         nsim_dev_port->ddir = debugfs_create_dir(port_ddir_name,
250                                                  nsim_dev->ports_ddir);
251         if (IS_ERR(nsim_dev_port->ddir))
252                 return PTR_ERR(nsim_dev_port->ddir);
253
254         sprintf(dev_link_name, "../../../" DRV_NAME "%u",
255                 nsim_dev->nsim_bus_dev->dev.id);
256         debugfs_create_symlink("dev", nsim_dev_port->ddir, dev_link_name);
257
258         return 0;
259 }
260
261 static void nsim_dev_port_debugfs_exit(struct nsim_dev_port *nsim_dev_port)
262 {
263         debugfs_remove_recursive(nsim_dev_port->ddir);
264 }
265
266 static int nsim_dev_resources_register(struct devlink *devlink)
267 {
268         struct devlink_resource_size_params params = {
269                 .size_max = (u64)-1,
270                 .size_granularity = 1,
271                 .unit = DEVLINK_RESOURCE_UNIT_ENTRY
272         };
273         int err;
274
275         /* Resources for IPv4 */
276         err = devlink_resource_register(devlink, "IPv4", (u64)-1,
277                                         NSIM_RESOURCE_IPV4,
278                                         DEVLINK_RESOURCE_ID_PARENT_TOP,
279                                         &params);
280         if (err) {
281                 pr_err("Failed to register IPv4 top resource\n");
282                 goto out;
283         }
284
285         err = devlink_resource_register(devlink, "fib", (u64)-1,
286                                         NSIM_RESOURCE_IPV4_FIB,
287                                         NSIM_RESOURCE_IPV4, &params);
288         if (err) {
289                 pr_err("Failed to register IPv4 FIB resource\n");
290                 return err;
291         }
292
293         err = devlink_resource_register(devlink, "fib-rules", (u64)-1,
294                                         NSIM_RESOURCE_IPV4_FIB_RULES,
295                                         NSIM_RESOURCE_IPV4, &params);
296         if (err) {
297                 pr_err("Failed to register IPv4 FIB rules resource\n");
298                 return err;
299         }
300
301         /* Resources for IPv6 */
302         err = devlink_resource_register(devlink, "IPv6", (u64)-1,
303                                         NSIM_RESOURCE_IPV6,
304                                         DEVLINK_RESOURCE_ID_PARENT_TOP,
305                                         &params);
306         if (err) {
307                 pr_err("Failed to register IPv6 top resource\n");
308                 goto out;
309         }
310
311         err = devlink_resource_register(devlink, "fib", (u64)-1,
312                                         NSIM_RESOURCE_IPV6_FIB,
313                                         NSIM_RESOURCE_IPV6, &params);
314         if (err) {
315                 pr_err("Failed to register IPv6 FIB resource\n");
316                 return err;
317         }
318
319         err = devlink_resource_register(devlink, "fib-rules", (u64)-1,
320                                         NSIM_RESOURCE_IPV6_FIB_RULES,
321                                         NSIM_RESOURCE_IPV6, &params);
322         if (err) {
323                 pr_err("Failed to register IPv6 FIB rules resource\n");
324                 return err;
325         }
326
327 out:
328         return err;
329 }
330
331 enum nsim_devlink_param_id {
332         NSIM_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
333         NSIM_DEVLINK_PARAM_ID_TEST1,
334 };
335
336 static const struct devlink_param nsim_devlink_params[] = {
337         DEVLINK_PARAM_GENERIC(MAX_MACS,
338                               BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
339                               NULL, NULL, NULL),
340         DEVLINK_PARAM_DRIVER(NSIM_DEVLINK_PARAM_ID_TEST1,
341                              "test1", DEVLINK_PARAM_TYPE_BOOL,
342                              BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
343                              NULL, NULL, NULL),
344 };
345
346 static void nsim_devlink_set_params_init_values(struct nsim_dev *nsim_dev,
347                                                 struct devlink *devlink)
348 {
349         union devlink_param_value value;
350
351         value.vu32 = nsim_dev->max_macs;
352         devlink_param_driverinit_value_set(devlink,
353                                            DEVLINK_PARAM_GENERIC_ID_MAX_MACS,
354                                            value);
355         value.vbool = nsim_dev->test1;
356         devlink_param_driverinit_value_set(devlink,
357                                            NSIM_DEVLINK_PARAM_ID_TEST1,
358                                            value);
359 }
360
361 static void nsim_devlink_param_load_driverinit_values(struct devlink *devlink)
362 {
363         struct nsim_dev *nsim_dev = devlink_priv(devlink);
364         union devlink_param_value saved_value;
365         int err;
366
367         err = devlink_param_driverinit_value_get(devlink,
368                                                  DEVLINK_PARAM_GENERIC_ID_MAX_MACS,
369                                                  &saved_value);
370         if (!err)
371                 nsim_dev->max_macs = saved_value.vu32;
372         err = devlink_param_driverinit_value_get(devlink,
373                                                  NSIM_DEVLINK_PARAM_ID_TEST1,
374                                                  &saved_value);
375         if (!err)
376                 nsim_dev->test1 = saved_value.vbool;
377 }
378
379 #define NSIM_DEV_DUMMY_REGION_SNAPSHOT_MAX 16
380
381 static const struct devlink_region_ops dummy_region_ops = {
382         .name = "dummy",
383         .destructor = &kfree,
384         .snapshot = nsim_dev_take_snapshot,
385 };
386
387 static int nsim_dev_dummy_region_init(struct nsim_dev *nsim_dev,
388                                       struct devlink *devlink)
389 {
390         nsim_dev->dummy_region =
391                 devlink_region_create(devlink, &dummy_region_ops,
392                                       NSIM_DEV_DUMMY_REGION_SNAPSHOT_MAX,
393                                       NSIM_DEV_DUMMY_REGION_SIZE);
394         return PTR_ERR_OR_ZERO(nsim_dev->dummy_region);
395 }
396
397 static void nsim_dev_dummy_region_exit(struct nsim_dev *nsim_dev)
398 {
399         devlink_region_destroy(nsim_dev->dummy_region);
400 }
401
402 struct nsim_trap_item {
403         void *trap_ctx;
404         enum devlink_trap_action action;
405 };
406
407 struct nsim_trap_data {
408         struct delayed_work trap_report_dw;
409         struct nsim_trap_item *trap_items_arr;
410         u64 *trap_policers_cnt_arr;
411         struct nsim_dev *nsim_dev;
412         spinlock_t trap_lock;   /* Protects trap_items_arr */
413 };
414
415 /* All driver-specific traps must be documented in
416  * Documentation/networking/devlink/netdevsim.rst
417  */
418 enum {
419         NSIM_TRAP_ID_BASE = DEVLINK_TRAP_GENERIC_ID_MAX,
420         NSIM_TRAP_ID_FID_MISS,
421 };
422
423 #define NSIM_TRAP_NAME_FID_MISS "fid_miss"
424
425 #define NSIM_TRAP_METADATA DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT
426
427 #define NSIM_TRAP_DROP(_id, _group_id)                                        \
428         DEVLINK_TRAP_GENERIC(DROP, DROP, _id,                                 \
429                              DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id,       \
430                              NSIM_TRAP_METADATA)
431 #define NSIM_TRAP_DROP_EXT(_id, _group_id, _metadata)                         \
432         DEVLINK_TRAP_GENERIC(DROP, DROP, _id,                                 \
433                              DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id,       \
434                              NSIM_TRAP_METADATA | (_metadata))
435 #define NSIM_TRAP_EXCEPTION(_id, _group_id)                                   \
436         DEVLINK_TRAP_GENERIC(EXCEPTION, TRAP, _id,                            \
437                              DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id,       \
438                              NSIM_TRAP_METADATA)
439 #define NSIM_TRAP_CONTROL(_id, _group_id, _action)                            \
440         DEVLINK_TRAP_GENERIC(CONTROL, _action, _id,                           \
441                              DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id,       \
442                              NSIM_TRAP_METADATA)
443 #define NSIM_TRAP_DRIVER_EXCEPTION(_id, _group_id)                            \
444         DEVLINK_TRAP_DRIVER(EXCEPTION, TRAP, NSIM_TRAP_ID_##_id,              \
445                             NSIM_TRAP_NAME_##_id,                             \
446                             DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id,        \
447                             NSIM_TRAP_METADATA)
448
449 #define NSIM_DEV_TRAP_POLICER_MIN_RATE  1
450 #define NSIM_DEV_TRAP_POLICER_MAX_RATE  8000
451 #define NSIM_DEV_TRAP_POLICER_MIN_BURST 8
452 #define NSIM_DEV_TRAP_POLICER_MAX_BURST 65536
453
454 #define NSIM_TRAP_POLICER(_id, _rate, _burst)                                 \
455         DEVLINK_TRAP_POLICER(_id, _rate, _burst,                              \
456                              NSIM_DEV_TRAP_POLICER_MAX_RATE,                  \
457                              NSIM_DEV_TRAP_POLICER_MIN_RATE,                  \
458                              NSIM_DEV_TRAP_POLICER_MAX_BURST,                 \
459                              NSIM_DEV_TRAP_POLICER_MIN_BURST)
460
461 static const struct devlink_trap_policer nsim_trap_policers_arr[] = {
462         NSIM_TRAP_POLICER(1, 1000, 128),
463         NSIM_TRAP_POLICER(2, 2000, 256),
464         NSIM_TRAP_POLICER(3, 3000, 512),
465 };
466
467 static const struct devlink_trap_group nsim_trap_groups_arr[] = {
468         DEVLINK_TRAP_GROUP_GENERIC(L2_DROPS, 0),
469         DEVLINK_TRAP_GROUP_GENERIC(L3_DROPS, 1),
470         DEVLINK_TRAP_GROUP_GENERIC(L3_EXCEPTIONS, 1),
471         DEVLINK_TRAP_GROUP_GENERIC(BUFFER_DROPS, 2),
472         DEVLINK_TRAP_GROUP_GENERIC(ACL_DROPS, 3),
473         DEVLINK_TRAP_GROUP_GENERIC(MC_SNOOPING, 3),
474 };
475
476 static const struct devlink_trap nsim_traps_arr[] = {
477         NSIM_TRAP_DROP(SMAC_MC, L2_DROPS),
478         NSIM_TRAP_DROP(VLAN_TAG_MISMATCH, L2_DROPS),
479         NSIM_TRAP_DROP(INGRESS_VLAN_FILTER, L2_DROPS),
480         NSIM_TRAP_DROP(INGRESS_STP_FILTER, L2_DROPS),
481         NSIM_TRAP_DROP(EMPTY_TX_LIST, L2_DROPS),
482         NSIM_TRAP_DROP(PORT_LOOPBACK_FILTER, L2_DROPS),
483         NSIM_TRAP_DRIVER_EXCEPTION(FID_MISS, L2_DROPS),
484         NSIM_TRAP_DROP(BLACKHOLE_ROUTE, L3_DROPS),
485         NSIM_TRAP_EXCEPTION(TTL_ERROR, L3_EXCEPTIONS),
486         NSIM_TRAP_DROP(TAIL_DROP, BUFFER_DROPS),
487         NSIM_TRAP_DROP_EXT(INGRESS_FLOW_ACTION_DROP, ACL_DROPS,
488                            DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE),
489         NSIM_TRAP_DROP_EXT(EGRESS_FLOW_ACTION_DROP, ACL_DROPS,
490                            DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE),
491         NSIM_TRAP_CONTROL(IGMP_QUERY, MC_SNOOPING, MIRROR),
492         NSIM_TRAP_CONTROL(IGMP_V1_REPORT, MC_SNOOPING, TRAP),
493 };
494
495 #define NSIM_TRAP_L4_DATA_LEN 100
496
497 static struct sk_buff *nsim_dev_trap_skb_build(void)
498 {
499         int tot_len, data_len = NSIM_TRAP_L4_DATA_LEN;
500         struct sk_buff *skb;
501         struct udphdr *udph;
502         struct ethhdr *eth;
503         struct iphdr *iph;
504
505         skb = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC);
506         if (!skb)
507                 return NULL;
508         tot_len = sizeof(struct iphdr) + sizeof(struct udphdr) + data_len;
509
510         skb_reset_mac_header(skb);
511         eth = skb_put(skb, sizeof(struct ethhdr));
512         eth_random_addr(eth->h_dest);
513         eth_random_addr(eth->h_source);
514         eth->h_proto = htons(ETH_P_IP);
515         skb->protocol = htons(ETH_P_IP);
516
517         skb_set_network_header(skb, skb->len);
518         iph = skb_put(skb, sizeof(struct iphdr));
519         iph->protocol = IPPROTO_UDP;
520         iph->saddr = in_aton("192.0.2.1");
521         iph->daddr = in_aton("198.51.100.1");
522         iph->version = 0x4;
523         iph->frag_off = 0;
524         iph->ihl = 0x5;
525         iph->tot_len = htons(tot_len);
526         iph->ttl = 100;
527         iph->check = 0;
528         iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
529
530         skb_set_transport_header(skb, skb->len);
531         udph = skb_put_zero(skb, sizeof(struct udphdr) + data_len);
532         get_random_bytes(&udph->source, sizeof(u16));
533         get_random_bytes(&udph->dest, sizeof(u16));
534         udph->len = htons(sizeof(struct udphdr) + data_len);
535
536         return skb;
537 }
538
539 static void nsim_dev_trap_report(struct nsim_dev_port *nsim_dev_port)
540 {
541         struct nsim_dev *nsim_dev = nsim_dev_port->ns->nsim_dev;
542         struct devlink *devlink = priv_to_devlink(nsim_dev);
543         struct nsim_trap_data *nsim_trap_data;
544         int i;
545
546         nsim_trap_data = nsim_dev->trap_data;
547
548         spin_lock(&nsim_trap_data->trap_lock);
549         for (i = 0; i < ARRAY_SIZE(nsim_traps_arr); i++) {
550                 struct flow_action_cookie *fa_cookie = NULL;
551                 struct nsim_trap_item *nsim_trap_item;
552                 struct sk_buff *skb;
553                 bool has_fa_cookie;
554
555                 has_fa_cookie = nsim_traps_arr[i].metadata_cap &
556                                 DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE;
557
558                 nsim_trap_item = &nsim_trap_data->trap_items_arr[i];
559                 if (nsim_trap_item->action == DEVLINK_TRAP_ACTION_DROP)
560                         continue;
561
562                 skb = nsim_dev_trap_skb_build();
563                 if (!skb)
564                         continue;
565                 skb->dev = nsim_dev_port->ns->netdev;
566
567                 /* Trapped packets are usually passed to devlink in softIRQ,
568                  * but in this case they are generated in a workqueue. Disable
569                  * softIRQs to prevent lockdep from complaining about
570                  * "incosistent lock state".
571                  */
572
573                 spin_lock_bh(&nsim_dev->fa_cookie_lock);
574                 fa_cookie = has_fa_cookie ? nsim_dev->fa_cookie : NULL;
575                 devlink_trap_report(devlink, skb, nsim_trap_item->trap_ctx,
576                                     &nsim_dev_port->devlink_port, fa_cookie);
577                 spin_unlock_bh(&nsim_dev->fa_cookie_lock);
578                 consume_skb(skb);
579         }
580         spin_unlock(&nsim_trap_data->trap_lock);
581 }
582
583 #define NSIM_TRAP_REPORT_INTERVAL_MS    100
584
585 static void nsim_dev_trap_report_work(struct work_struct *work)
586 {
587         struct nsim_trap_data *nsim_trap_data;
588         struct nsim_dev_port *nsim_dev_port;
589         struct nsim_dev *nsim_dev;
590
591         nsim_trap_data = container_of(work, struct nsim_trap_data,
592                                       trap_report_dw.work);
593         nsim_dev = nsim_trap_data->nsim_dev;
594
595         /* For each running port and enabled packet trap, generate a UDP
596          * packet with a random 5-tuple and report it.
597          */
598         mutex_lock(&nsim_dev->port_list_lock);
599         list_for_each_entry(nsim_dev_port, &nsim_dev->port_list, list) {
600                 if (!netif_running(nsim_dev_port->ns->netdev))
601                         continue;
602
603                 nsim_dev_trap_report(nsim_dev_port);
604         }
605         mutex_unlock(&nsim_dev->port_list_lock);
606
607         schedule_delayed_work(&nsim_dev->trap_data->trap_report_dw,
608                               msecs_to_jiffies(NSIM_TRAP_REPORT_INTERVAL_MS));
609 }
610
611 static int nsim_dev_traps_init(struct devlink *devlink)
612 {
613         size_t policers_count = ARRAY_SIZE(nsim_trap_policers_arr);
614         struct nsim_dev *nsim_dev = devlink_priv(devlink);
615         struct nsim_trap_data *nsim_trap_data;
616         int err;
617
618         nsim_trap_data = kzalloc(sizeof(*nsim_trap_data), GFP_KERNEL);
619         if (!nsim_trap_data)
620                 return -ENOMEM;
621
622         nsim_trap_data->trap_items_arr = kcalloc(ARRAY_SIZE(nsim_traps_arr),
623                                                  sizeof(struct nsim_trap_item),
624                                                  GFP_KERNEL);
625         if (!nsim_trap_data->trap_items_arr) {
626                 err = -ENOMEM;
627                 goto err_trap_data_free;
628         }
629
630         nsim_trap_data->trap_policers_cnt_arr = kcalloc(policers_count,
631                                                         sizeof(u64),
632                                                         GFP_KERNEL);
633         if (!nsim_trap_data->trap_policers_cnt_arr) {
634                 err = -ENOMEM;
635                 goto err_trap_items_free;
636         }
637
638         /* The lock is used to protect the action state of the registered
639          * traps. The value is written by user and read in delayed work when
640          * iterating over all the traps.
641          */
642         spin_lock_init(&nsim_trap_data->trap_lock);
643         nsim_trap_data->nsim_dev = nsim_dev;
644         nsim_dev->trap_data = nsim_trap_data;
645
646         err = devlink_trap_policers_register(devlink, nsim_trap_policers_arr,
647                                              policers_count);
648         if (err)
649                 goto err_trap_policers_cnt_free;
650
651         err = devlink_trap_groups_register(devlink, nsim_trap_groups_arr,
652                                            ARRAY_SIZE(nsim_trap_groups_arr));
653         if (err)
654                 goto err_trap_policers_unregister;
655
656         err = devlink_traps_register(devlink, nsim_traps_arr,
657                                      ARRAY_SIZE(nsim_traps_arr), NULL);
658         if (err)
659                 goto err_trap_groups_unregister;
660
661         INIT_DELAYED_WORK(&nsim_dev->trap_data->trap_report_dw,
662                           nsim_dev_trap_report_work);
663         schedule_delayed_work(&nsim_dev->trap_data->trap_report_dw,
664                               msecs_to_jiffies(NSIM_TRAP_REPORT_INTERVAL_MS));
665
666         return 0;
667
668 err_trap_groups_unregister:
669         devlink_trap_groups_unregister(devlink, nsim_trap_groups_arr,
670                                        ARRAY_SIZE(nsim_trap_groups_arr));
671 err_trap_policers_unregister:
672         devlink_trap_policers_unregister(devlink, nsim_trap_policers_arr,
673                                          ARRAY_SIZE(nsim_trap_policers_arr));
674 err_trap_policers_cnt_free:
675         kfree(nsim_trap_data->trap_policers_cnt_arr);
676 err_trap_items_free:
677         kfree(nsim_trap_data->trap_items_arr);
678 err_trap_data_free:
679         kfree(nsim_trap_data);
680         return err;
681 }
682
683 static void nsim_dev_traps_exit(struct devlink *devlink)
684 {
685         struct nsim_dev *nsim_dev = devlink_priv(devlink);
686
687         cancel_delayed_work_sync(&nsim_dev->trap_data->trap_report_dw);
688         devlink_traps_unregister(devlink, nsim_traps_arr,
689                                  ARRAY_SIZE(nsim_traps_arr));
690         devlink_trap_groups_unregister(devlink, nsim_trap_groups_arr,
691                                        ARRAY_SIZE(nsim_trap_groups_arr));
692         devlink_trap_policers_unregister(devlink, nsim_trap_policers_arr,
693                                          ARRAY_SIZE(nsim_trap_policers_arr));
694         kfree(nsim_dev->trap_data->trap_policers_cnt_arr);
695         kfree(nsim_dev->trap_data->trap_items_arr);
696         kfree(nsim_dev->trap_data);
697 }
698
699 static int nsim_dev_reload_create(struct nsim_dev *nsim_dev,
700                                   struct netlink_ext_ack *extack);
701 static void nsim_dev_reload_destroy(struct nsim_dev *nsim_dev);
702
703 static int nsim_dev_reload_down(struct devlink *devlink, bool netns_change,
704                                 enum devlink_reload_action action, enum devlink_reload_limit limit,
705                                 struct netlink_ext_ack *extack)
706 {
707         struct nsim_dev *nsim_dev = devlink_priv(devlink);
708
709         if (nsim_dev->dont_allow_reload) {
710                 /* For testing purposes, user set debugfs dont_allow_reload
711                  * value to true. So forbid it.
712                  */
713                 NL_SET_ERR_MSG_MOD(extack, "User forbid the reload for testing purposes");
714                 return -EOPNOTSUPP;
715         }
716
717         nsim_dev_reload_destroy(nsim_dev);
718         return 0;
719 }
720
721 static int nsim_dev_reload_up(struct devlink *devlink, enum devlink_reload_action action,
722                               enum devlink_reload_limit limit, u32 *actions_performed,
723                               struct netlink_ext_ack *extack)
724 {
725         struct nsim_dev *nsim_dev = devlink_priv(devlink);
726
727         if (nsim_dev->fail_reload) {
728                 /* For testing purposes, user set debugfs fail_reload
729                  * value to true. Fail right away.
730                  */
731                 NL_SET_ERR_MSG_MOD(extack, "User setup the reload to fail for testing purposes");
732                 return -EINVAL;
733         }
734
735         *actions_performed = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT);
736         return nsim_dev_reload_create(nsim_dev, extack);
737 }
738
739 static int nsim_dev_info_get(struct devlink *devlink,
740                              struct devlink_info_req *req,
741                              struct netlink_ext_ack *extack)
742 {
743         return devlink_info_driver_name_put(req, DRV_NAME);
744 }
745
746 #define NSIM_DEV_FLASH_SIZE 500000
747 #define NSIM_DEV_FLASH_CHUNK_SIZE 1000
748 #define NSIM_DEV_FLASH_CHUNK_TIME_MS 10
749
750 static int nsim_dev_flash_update(struct devlink *devlink,
751                                  struct devlink_flash_update_params *params,
752                                  struct netlink_ext_ack *extack)
753 {
754         struct nsim_dev *nsim_dev = devlink_priv(devlink);
755         int i;
756
757         if ((params->overwrite_mask & ~nsim_dev->fw_update_overwrite_mask) != 0)
758                 return -EOPNOTSUPP;
759
760         if (nsim_dev->fw_update_status) {
761                 devlink_flash_update_begin_notify(devlink);
762                 devlink_flash_update_status_notify(devlink,
763                                                    "Preparing to flash",
764                                                    params->component, 0, 0);
765         }
766
767         for (i = 0; i < NSIM_DEV_FLASH_SIZE / NSIM_DEV_FLASH_CHUNK_SIZE; i++) {
768                 if (nsim_dev->fw_update_status)
769                         devlink_flash_update_status_notify(devlink, "Flashing",
770                                                            params->component,
771                                                            i * NSIM_DEV_FLASH_CHUNK_SIZE,
772                                                            NSIM_DEV_FLASH_SIZE);
773                 msleep(NSIM_DEV_FLASH_CHUNK_TIME_MS);
774         }
775
776         if (nsim_dev->fw_update_status) {
777                 devlink_flash_update_status_notify(devlink, "Flashing",
778                                                    params->component,
779                                                    NSIM_DEV_FLASH_SIZE,
780                                                    NSIM_DEV_FLASH_SIZE);
781                 devlink_flash_update_timeout_notify(devlink, "Flash select",
782                                                     params->component, 81);
783                 devlink_flash_update_status_notify(devlink, "Flashing done",
784                                                    params->component, 0, 0);
785                 devlink_flash_update_end_notify(devlink);
786         }
787
788         return 0;
789 }
790
791 static struct nsim_trap_item *
792 nsim_dev_trap_item_lookup(struct nsim_dev *nsim_dev, u16 trap_id)
793 {
794         struct nsim_trap_data *nsim_trap_data = nsim_dev->trap_data;
795         int i;
796
797         for (i = 0; i < ARRAY_SIZE(nsim_traps_arr); i++) {
798                 if (nsim_traps_arr[i].id == trap_id)
799                         return &nsim_trap_data->trap_items_arr[i];
800         }
801
802         return NULL;
803 }
804
805 static int nsim_dev_devlink_trap_init(struct devlink *devlink,
806                                       const struct devlink_trap *trap,
807                                       void *trap_ctx)
808 {
809         struct nsim_dev *nsim_dev = devlink_priv(devlink);
810         struct nsim_trap_item *nsim_trap_item;
811
812         nsim_trap_item = nsim_dev_trap_item_lookup(nsim_dev, trap->id);
813         if (WARN_ON(!nsim_trap_item))
814                 return -ENOENT;
815
816         nsim_trap_item->trap_ctx = trap_ctx;
817         nsim_trap_item->action = trap->init_action;
818
819         return 0;
820 }
821
822 static int
823 nsim_dev_devlink_trap_action_set(struct devlink *devlink,
824                                  const struct devlink_trap *trap,
825                                  enum devlink_trap_action action,
826                                  struct netlink_ext_ack *extack)
827 {
828         struct nsim_dev *nsim_dev = devlink_priv(devlink);
829         struct nsim_trap_item *nsim_trap_item;
830
831         nsim_trap_item = nsim_dev_trap_item_lookup(nsim_dev, trap->id);
832         if (WARN_ON(!nsim_trap_item))
833                 return -ENOENT;
834
835         spin_lock(&nsim_dev->trap_data->trap_lock);
836         nsim_trap_item->action = action;
837         spin_unlock(&nsim_dev->trap_data->trap_lock);
838
839         return 0;
840 }
841
842 static int
843 nsim_dev_devlink_trap_group_set(struct devlink *devlink,
844                                 const struct devlink_trap_group *group,
845                                 const struct devlink_trap_policer *policer,
846                                 struct netlink_ext_ack *extack)
847 {
848         struct nsim_dev *nsim_dev = devlink_priv(devlink);
849
850         if (nsim_dev->fail_trap_group_set)
851                 return -EINVAL;
852
853         return 0;
854 }
855
856 static int
857 nsim_dev_devlink_trap_policer_set(struct devlink *devlink,
858                                   const struct devlink_trap_policer *policer,
859                                   u64 rate, u64 burst,
860                                   struct netlink_ext_ack *extack)
861 {
862         struct nsim_dev *nsim_dev = devlink_priv(devlink);
863
864         if (nsim_dev->fail_trap_policer_set) {
865                 NL_SET_ERR_MSG_MOD(extack, "User setup the operation to fail for testing purposes");
866                 return -EINVAL;
867         }
868
869         return 0;
870 }
871
872 static int
873 nsim_dev_devlink_trap_policer_counter_get(struct devlink *devlink,
874                                           const struct devlink_trap_policer *policer,
875                                           u64 *p_drops)
876 {
877         struct nsim_dev *nsim_dev = devlink_priv(devlink);
878         u64 *cnt;
879
880         if (nsim_dev->fail_trap_policer_counter_get)
881                 return -EINVAL;
882
883         cnt = &nsim_dev->trap_data->trap_policers_cnt_arr[policer->id - 1];
884         *p_drops = (*cnt)++;
885
886         return 0;
887 }
888
889 static const struct devlink_ops nsim_dev_devlink_ops = {
890         .supported_flash_update_params = DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT |
891                                          DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK,
892         .reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT),
893         .reload_down = nsim_dev_reload_down,
894         .reload_up = nsim_dev_reload_up,
895         .info_get = nsim_dev_info_get,
896         .flash_update = nsim_dev_flash_update,
897         .trap_init = nsim_dev_devlink_trap_init,
898         .trap_action_set = nsim_dev_devlink_trap_action_set,
899         .trap_group_set = nsim_dev_devlink_trap_group_set,
900         .trap_policer_set = nsim_dev_devlink_trap_policer_set,
901         .trap_policer_counter_get = nsim_dev_devlink_trap_policer_counter_get,
902 };
903
904 #define NSIM_DEV_MAX_MACS_DEFAULT 32
905 #define NSIM_DEV_TEST1_DEFAULT true
906
907 static int __nsim_dev_port_add(struct nsim_dev *nsim_dev,
908                                unsigned int port_index)
909 {
910         struct devlink_port_attrs attrs = {};
911         struct nsim_dev_port *nsim_dev_port;
912         struct devlink_port *devlink_port;
913         int err;
914
915         nsim_dev_port = kzalloc(sizeof(*nsim_dev_port), GFP_KERNEL);
916         if (!nsim_dev_port)
917                 return -ENOMEM;
918         nsim_dev_port->port_index = port_index;
919
920         devlink_port = &nsim_dev_port->devlink_port;
921         attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
922         attrs.phys.port_number = port_index + 1;
923         memcpy(attrs.switch_id.id, nsim_dev->switch_id.id, nsim_dev->switch_id.id_len);
924         attrs.switch_id.id_len = nsim_dev->switch_id.id_len;
925         devlink_port_attrs_set(devlink_port, &attrs);
926         err = devlink_port_register(priv_to_devlink(nsim_dev), devlink_port,
927                                     port_index);
928         if (err)
929                 goto err_port_free;
930
931         err = nsim_dev_port_debugfs_init(nsim_dev, nsim_dev_port);
932         if (err)
933                 goto err_dl_port_unregister;
934
935         nsim_dev_port->ns = nsim_create(nsim_dev, nsim_dev_port);
936         if (IS_ERR(nsim_dev_port->ns)) {
937                 err = PTR_ERR(nsim_dev_port->ns);
938                 goto err_port_debugfs_exit;
939         }
940
941         devlink_port_type_eth_set(devlink_port, nsim_dev_port->ns->netdev);
942         list_add(&nsim_dev_port->list, &nsim_dev->port_list);
943
944         return 0;
945
946 err_port_debugfs_exit:
947         nsim_dev_port_debugfs_exit(nsim_dev_port);
948 err_dl_port_unregister:
949         devlink_port_unregister(devlink_port);
950 err_port_free:
951         kfree(nsim_dev_port);
952         return err;
953 }
954
955 static void __nsim_dev_port_del(struct nsim_dev_port *nsim_dev_port)
956 {
957         struct devlink_port *devlink_port = &nsim_dev_port->devlink_port;
958
959         list_del(&nsim_dev_port->list);
960         devlink_port_type_clear(devlink_port);
961         nsim_destroy(nsim_dev_port->ns);
962         nsim_dev_port_debugfs_exit(nsim_dev_port);
963         devlink_port_unregister(devlink_port);
964         kfree(nsim_dev_port);
965 }
966
967 static void nsim_dev_port_del_all(struct nsim_dev *nsim_dev)
968 {
969         struct nsim_dev_port *nsim_dev_port, *tmp;
970
971         mutex_lock(&nsim_dev->port_list_lock);
972         list_for_each_entry_safe(nsim_dev_port, tmp,
973                                  &nsim_dev->port_list, list)
974                 __nsim_dev_port_del(nsim_dev_port);
975         mutex_unlock(&nsim_dev->port_list_lock);
976 }
977
978 static int nsim_dev_port_add_all(struct nsim_dev *nsim_dev,
979                                  unsigned int port_count)
980 {
981         int i, err;
982
983         for (i = 0; i < port_count; i++) {
984                 err = __nsim_dev_port_add(nsim_dev, i);
985                 if (err)
986                         goto err_port_del_all;
987         }
988         return 0;
989
990 err_port_del_all:
991         nsim_dev_port_del_all(nsim_dev);
992         return err;
993 }
994
995 static int nsim_dev_reload_create(struct nsim_dev *nsim_dev,
996                                   struct netlink_ext_ack *extack)
997 {
998         struct nsim_bus_dev *nsim_bus_dev = nsim_dev->nsim_bus_dev;
999         struct devlink *devlink;
1000         int err;
1001
1002         devlink = priv_to_devlink(nsim_dev);
1003         nsim_dev = devlink_priv(devlink);
1004         INIT_LIST_HEAD(&nsim_dev->port_list);
1005         mutex_init(&nsim_dev->port_list_lock);
1006         nsim_dev->fw_update_status = true;
1007         nsim_dev->fw_update_overwrite_mask = 0;
1008
1009         nsim_dev->fib_data = nsim_fib_create(devlink, extack);
1010         if (IS_ERR(nsim_dev->fib_data))
1011                 return PTR_ERR(nsim_dev->fib_data);
1012
1013         nsim_devlink_param_load_driverinit_values(devlink);
1014
1015         err = nsim_dev_dummy_region_init(nsim_dev, devlink);
1016         if (err)
1017                 goto err_fib_destroy;
1018
1019         err = nsim_dev_traps_init(devlink);
1020         if (err)
1021                 goto err_dummy_region_exit;
1022
1023         err = nsim_dev_health_init(nsim_dev, devlink);
1024         if (err)
1025                 goto err_traps_exit;
1026
1027         err = nsim_dev_port_add_all(nsim_dev, nsim_bus_dev->port_count);
1028         if (err)
1029                 goto err_health_exit;
1030
1031         nsim_dev->take_snapshot = debugfs_create_file("take_snapshot",
1032                                                       0200,
1033                                                       nsim_dev->ddir,
1034                                                       nsim_dev,
1035                                                 &nsim_dev_take_snapshot_fops);
1036         return 0;
1037
1038 err_health_exit:
1039         nsim_dev_health_exit(nsim_dev);
1040 err_traps_exit:
1041         nsim_dev_traps_exit(devlink);
1042 err_dummy_region_exit:
1043         nsim_dev_dummy_region_exit(nsim_dev);
1044 err_fib_destroy:
1045         nsim_fib_destroy(devlink, nsim_dev->fib_data);
1046         return err;
1047 }
1048
1049 int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev)
1050 {
1051         struct nsim_dev *nsim_dev;
1052         struct devlink *devlink;
1053         int err;
1054
1055         devlink = devlink_alloc(&nsim_dev_devlink_ops, sizeof(*nsim_dev));
1056         if (!devlink)
1057                 return -ENOMEM;
1058         devlink_net_set(devlink, nsim_bus_dev->initial_net);
1059         nsim_dev = devlink_priv(devlink);
1060         nsim_dev->nsim_bus_dev = nsim_bus_dev;
1061         nsim_dev->switch_id.id_len = sizeof(nsim_dev->switch_id.id);
1062         get_random_bytes(nsim_dev->switch_id.id, nsim_dev->switch_id.id_len);
1063         INIT_LIST_HEAD(&nsim_dev->port_list);
1064         mutex_init(&nsim_dev->port_list_lock);
1065         nsim_dev->fw_update_status = true;
1066         nsim_dev->fw_update_overwrite_mask = 0;
1067         nsim_dev->max_macs = NSIM_DEV_MAX_MACS_DEFAULT;
1068         nsim_dev->test1 = NSIM_DEV_TEST1_DEFAULT;
1069         spin_lock_init(&nsim_dev->fa_cookie_lock);
1070
1071         dev_set_drvdata(&nsim_bus_dev->dev, nsim_dev);
1072
1073         err = nsim_dev_resources_register(devlink);
1074         if (err)
1075                 goto err_devlink_free;
1076
1077         nsim_dev->fib_data = nsim_fib_create(devlink, NULL);
1078         if (IS_ERR(nsim_dev->fib_data)) {
1079                 err = PTR_ERR(nsim_dev->fib_data);
1080                 goto err_resources_unregister;
1081         }
1082
1083         err = devlink_register(devlink, &nsim_bus_dev->dev);
1084         if (err)
1085                 goto err_fib_destroy;
1086
1087         err = devlink_params_register(devlink, nsim_devlink_params,
1088                                       ARRAY_SIZE(nsim_devlink_params));
1089         if (err)
1090                 goto err_dl_unregister;
1091         nsim_devlink_set_params_init_values(nsim_dev, devlink);
1092
1093         err = nsim_dev_dummy_region_init(nsim_dev, devlink);
1094         if (err)
1095                 goto err_params_unregister;
1096
1097         err = nsim_dev_traps_init(devlink);
1098         if (err)
1099                 goto err_dummy_region_exit;
1100
1101         err = nsim_dev_debugfs_init(nsim_dev);
1102         if (err)
1103                 goto err_traps_exit;
1104
1105         err = nsim_dev_health_init(nsim_dev, devlink);
1106         if (err)
1107                 goto err_debugfs_exit;
1108
1109         err = nsim_bpf_dev_init(nsim_dev);
1110         if (err)
1111                 goto err_health_exit;
1112
1113         err = nsim_dev_port_add_all(nsim_dev, nsim_bus_dev->port_count);
1114         if (err)
1115                 goto err_bpf_dev_exit;
1116
1117         devlink_params_publish(devlink);
1118         devlink_reload_enable(devlink);
1119         return 0;
1120
1121 err_bpf_dev_exit:
1122         nsim_bpf_dev_exit(nsim_dev);
1123 err_health_exit:
1124         nsim_dev_health_exit(nsim_dev);
1125 err_debugfs_exit:
1126         nsim_dev_debugfs_exit(nsim_dev);
1127 err_traps_exit:
1128         nsim_dev_traps_exit(devlink);
1129 err_dummy_region_exit:
1130         nsim_dev_dummy_region_exit(nsim_dev);
1131 err_params_unregister:
1132         devlink_params_unregister(devlink, nsim_devlink_params,
1133                                   ARRAY_SIZE(nsim_devlink_params));
1134 err_dl_unregister:
1135         devlink_unregister(devlink);
1136 err_fib_destroy:
1137         nsim_fib_destroy(devlink, nsim_dev->fib_data);
1138 err_resources_unregister:
1139         devlink_resources_unregister(devlink, NULL);
1140 err_devlink_free:
1141         devlink_free(devlink);
1142         return err;
1143 }
1144
1145 static void nsim_dev_reload_destroy(struct nsim_dev *nsim_dev)
1146 {
1147         struct devlink *devlink = priv_to_devlink(nsim_dev);
1148
1149         if (devlink_is_reload_failed(devlink))
1150                 return;
1151         debugfs_remove(nsim_dev->take_snapshot);
1152         nsim_dev_port_del_all(nsim_dev);
1153         nsim_dev_health_exit(nsim_dev);
1154         nsim_dev_traps_exit(devlink);
1155         nsim_dev_dummy_region_exit(nsim_dev);
1156         mutex_destroy(&nsim_dev->port_list_lock);
1157         nsim_fib_destroy(devlink, nsim_dev->fib_data);
1158 }
1159
1160 void nsim_dev_remove(struct nsim_bus_dev *nsim_bus_dev)
1161 {
1162         struct nsim_dev *nsim_dev = dev_get_drvdata(&nsim_bus_dev->dev);
1163         struct devlink *devlink = priv_to_devlink(nsim_dev);
1164
1165         devlink_reload_disable(devlink);
1166
1167         nsim_dev_reload_destroy(nsim_dev);
1168
1169         nsim_bpf_dev_exit(nsim_dev);
1170         nsim_dev_debugfs_exit(nsim_dev);
1171         devlink_params_unregister(devlink, nsim_devlink_params,
1172                                   ARRAY_SIZE(nsim_devlink_params));
1173         devlink_unregister(devlink);
1174         devlink_resources_unregister(devlink, NULL);
1175         devlink_free(devlink);
1176 }
1177
1178 static struct nsim_dev_port *
1179 __nsim_dev_port_lookup(struct nsim_dev *nsim_dev, unsigned int port_index)
1180 {
1181         struct nsim_dev_port *nsim_dev_port;
1182
1183         list_for_each_entry(nsim_dev_port, &nsim_dev->port_list, list)
1184                 if (nsim_dev_port->port_index == port_index)
1185                         return nsim_dev_port;
1186         return NULL;
1187 }
1188
1189 int nsim_dev_port_add(struct nsim_bus_dev *nsim_bus_dev,
1190                       unsigned int port_index)
1191 {
1192         struct nsim_dev *nsim_dev = dev_get_drvdata(&nsim_bus_dev->dev);
1193         int err;
1194
1195         mutex_lock(&nsim_dev->port_list_lock);
1196         if (__nsim_dev_port_lookup(nsim_dev, port_index))
1197                 err = -EEXIST;
1198         else
1199                 err = __nsim_dev_port_add(nsim_dev, port_index);
1200         mutex_unlock(&nsim_dev->port_list_lock);
1201         return err;
1202 }
1203
1204 int nsim_dev_port_del(struct nsim_bus_dev *nsim_bus_dev,
1205                       unsigned int port_index)
1206 {
1207         struct nsim_dev *nsim_dev = dev_get_drvdata(&nsim_bus_dev->dev);
1208         struct nsim_dev_port *nsim_dev_port;
1209         int err = 0;
1210
1211         mutex_lock(&nsim_dev->port_list_lock);
1212         nsim_dev_port = __nsim_dev_port_lookup(nsim_dev, port_index);
1213         if (!nsim_dev_port)
1214                 err = -ENOENT;
1215         else
1216                 __nsim_dev_port_del(nsim_dev_port);
1217         mutex_unlock(&nsim_dev->port_list_lock);
1218         return err;
1219 }
1220
1221 int nsim_dev_init(void)
1222 {
1223         nsim_dev_ddir = debugfs_create_dir(DRV_NAME, NULL);
1224         return PTR_ERR_OR_ZERO(nsim_dev_ddir);
1225 }
1226
1227 void nsim_dev_exit(void)
1228 {
1229         debugfs_remove_recursive(nsim_dev_ddir);
1230 }