xref: /openbmc/linux/drivers/infiniband/hw/mlx5/macsec.c (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
1758ce14aSPatrisious Haddad // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2758ce14aSPatrisious Haddad /* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. */
3758ce14aSPatrisious Haddad 
4758ce14aSPatrisious Haddad #include "macsec.h"
5*58dbd642SPatrisious Haddad #include <linux/mlx5/macsec.h>
6758ce14aSPatrisious Haddad 
7758ce14aSPatrisious Haddad struct mlx5_reserved_gids {
8758ce14aSPatrisious Haddad 	int macsec_index;
9758ce14aSPatrisious Haddad 	const struct ib_gid_attr *physical_gid;
10758ce14aSPatrisious Haddad };
11758ce14aSPatrisious Haddad 
12*58dbd642SPatrisious Haddad struct mlx5_roce_gids {
13*58dbd642SPatrisious Haddad 	struct list_head roce_gid_list_entry;
14*58dbd642SPatrisious Haddad 	u16 gid_idx;
15*58dbd642SPatrisious Haddad 	union {
16*58dbd642SPatrisious Haddad 		struct sockaddr_in  sockaddr_in;
17*58dbd642SPatrisious Haddad 		struct sockaddr_in6 sockaddr_in6;
18*58dbd642SPatrisious Haddad 	} addr;
19*58dbd642SPatrisious Haddad };
20*58dbd642SPatrisious Haddad 
21*58dbd642SPatrisious Haddad struct mlx5_macsec_device {
22*58dbd642SPatrisious Haddad 	struct list_head macsec_devices_list_entry;
23*58dbd642SPatrisious Haddad 	void *macdev;
24*58dbd642SPatrisious Haddad 	struct list_head macsec_roce_gids;
25*58dbd642SPatrisious Haddad 	struct list_head tx_rules_list;
26*58dbd642SPatrisious Haddad 	struct list_head rx_rules_list;
27*58dbd642SPatrisious Haddad };
28*58dbd642SPatrisious Haddad 
cleanup_macsec_device(struct mlx5_macsec_device * macsec_device)29*58dbd642SPatrisious Haddad static void cleanup_macsec_device(struct mlx5_macsec_device *macsec_device)
30*58dbd642SPatrisious Haddad {
31*58dbd642SPatrisious Haddad 	if (!list_empty(&macsec_device->tx_rules_list) ||
32*58dbd642SPatrisious Haddad 	    !list_empty(&macsec_device->rx_rules_list) ||
33*58dbd642SPatrisious Haddad 	    !list_empty(&macsec_device->macsec_roce_gids))
34*58dbd642SPatrisious Haddad 		return;
35*58dbd642SPatrisious Haddad 
36*58dbd642SPatrisious Haddad 	list_del(&macsec_device->macsec_devices_list_entry);
37*58dbd642SPatrisious Haddad 	kfree(macsec_device);
38*58dbd642SPatrisious Haddad }
39*58dbd642SPatrisious Haddad 
get_macsec_device(void * macdev,struct list_head * macsec_devices_list)40*58dbd642SPatrisious Haddad static struct mlx5_macsec_device *get_macsec_device(void *macdev,
41*58dbd642SPatrisious Haddad 						    struct list_head *macsec_devices_list)
42*58dbd642SPatrisious Haddad {
43*58dbd642SPatrisious Haddad 	struct mlx5_macsec_device *iter, *macsec_device = NULL;
44*58dbd642SPatrisious Haddad 
45*58dbd642SPatrisious Haddad 	list_for_each_entry(iter, macsec_devices_list, macsec_devices_list_entry) {
46*58dbd642SPatrisious Haddad 		if (iter->macdev == macdev) {
47*58dbd642SPatrisious Haddad 			macsec_device = iter;
48*58dbd642SPatrisious Haddad 			break;
49*58dbd642SPatrisious Haddad 		}
50*58dbd642SPatrisious Haddad 	}
51*58dbd642SPatrisious Haddad 
52*58dbd642SPatrisious Haddad 	if (macsec_device)
53*58dbd642SPatrisious Haddad 		return macsec_device;
54*58dbd642SPatrisious Haddad 
55*58dbd642SPatrisious Haddad 	macsec_device = kzalloc(sizeof(*macsec_device), GFP_KERNEL);
56*58dbd642SPatrisious Haddad 	if (!macsec_device)
57*58dbd642SPatrisious Haddad 		return NULL;
58*58dbd642SPatrisious Haddad 
59*58dbd642SPatrisious Haddad 	macsec_device->macdev = macdev;
60*58dbd642SPatrisious Haddad 	INIT_LIST_HEAD(&macsec_device->tx_rules_list);
61*58dbd642SPatrisious Haddad 	INIT_LIST_HEAD(&macsec_device->rx_rules_list);
62*58dbd642SPatrisious Haddad 	INIT_LIST_HEAD(&macsec_device->macsec_roce_gids);
63*58dbd642SPatrisious Haddad 	list_add(&macsec_device->macsec_devices_list_entry, macsec_devices_list);
64*58dbd642SPatrisious Haddad 
65*58dbd642SPatrisious Haddad 	return macsec_device;
66*58dbd642SPatrisious Haddad }
67*58dbd642SPatrisious Haddad 
mlx5_macsec_del_roce_gid(struct mlx5_macsec_device * macsec_device,u16 gid_idx)68*58dbd642SPatrisious Haddad static void mlx5_macsec_del_roce_gid(struct mlx5_macsec_device *macsec_device, u16 gid_idx)
69*58dbd642SPatrisious Haddad {
70*58dbd642SPatrisious Haddad 	struct mlx5_roce_gids *current_gid, *next_gid;
71*58dbd642SPatrisious Haddad 
72*58dbd642SPatrisious Haddad 	list_for_each_entry_safe(current_gid, next_gid, &macsec_device->macsec_roce_gids,
73*58dbd642SPatrisious Haddad 				 roce_gid_list_entry)
74*58dbd642SPatrisious Haddad 		if (current_gid->gid_idx == gid_idx) {
75*58dbd642SPatrisious Haddad 			list_del(&current_gid->roce_gid_list_entry);
76*58dbd642SPatrisious Haddad 			kfree(current_gid);
77*58dbd642SPatrisious Haddad 		}
78*58dbd642SPatrisious Haddad }
79*58dbd642SPatrisious Haddad 
mlx5_macsec_save_roce_gid(struct mlx5_macsec_device * macsec_device,const struct sockaddr * addr,u16 gid_idx)80*58dbd642SPatrisious Haddad static void mlx5_macsec_save_roce_gid(struct mlx5_macsec_device *macsec_device,
81*58dbd642SPatrisious Haddad 				      const struct sockaddr *addr, u16 gid_idx)
82*58dbd642SPatrisious Haddad {
83*58dbd642SPatrisious Haddad 	struct mlx5_roce_gids *roce_gids;
84*58dbd642SPatrisious Haddad 
85*58dbd642SPatrisious Haddad 	roce_gids = kzalloc(sizeof(*roce_gids), GFP_KERNEL);
86*58dbd642SPatrisious Haddad 	if (!roce_gids)
87*58dbd642SPatrisious Haddad 		return;
88*58dbd642SPatrisious Haddad 
89*58dbd642SPatrisious Haddad 	roce_gids->gid_idx = gid_idx;
90*58dbd642SPatrisious Haddad 	if (addr->sa_family == AF_INET)
91*58dbd642SPatrisious Haddad 		memcpy(&roce_gids->addr.sockaddr_in, addr, sizeof(roce_gids->addr.sockaddr_in));
92*58dbd642SPatrisious Haddad 	else
93*58dbd642SPatrisious Haddad 		memcpy(&roce_gids->addr.sockaddr_in6, addr, sizeof(roce_gids->addr.sockaddr_in6));
94*58dbd642SPatrisious Haddad 
95*58dbd642SPatrisious Haddad 	list_add_tail(&roce_gids->roce_gid_list_entry, &macsec_device->macsec_roce_gids);
96*58dbd642SPatrisious Haddad }
97*58dbd642SPatrisious Haddad 
handle_macsec_gids(struct list_head * macsec_devices_list,struct mlx5_macsec_event_data * data)98*58dbd642SPatrisious Haddad static void handle_macsec_gids(struct list_head *macsec_devices_list,
99*58dbd642SPatrisious Haddad 			       struct mlx5_macsec_event_data *data)
100*58dbd642SPatrisious Haddad {
101*58dbd642SPatrisious Haddad 	struct mlx5_macsec_device *macsec_device;
102*58dbd642SPatrisious Haddad 	struct mlx5_roce_gids *gid;
103*58dbd642SPatrisious Haddad 
104*58dbd642SPatrisious Haddad 	macsec_device = get_macsec_device(data->macdev, macsec_devices_list);
105*58dbd642SPatrisious Haddad 	if (!macsec_device)
106*58dbd642SPatrisious Haddad 		return;
107*58dbd642SPatrisious Haddad 
108*58dbd642SPatrisious Haddad 	list_for_each_entry(gid, &macsec_device->macsec_roce_gids, roce_gid_list_entry) {
109*58dbd642SPatrisious Haddad 		mlx5_macsec_add_roce_sa_rules(data->fs_id, (struct sockaddr *)&gid->addr,
110*58dbd642SPatrisious Haddad 					      gid->gid_idx, &macsec_device->tx_rules_list,
111*58dbd642SPatrisious Haddad 					      &macsec_device->rx_rules_list, data->macsec_fs,
112*58dbd642SPatrisious Haddad 					      data->is_tx);
113*58dbd642SPatrisious Haddad 	}
114*58dbd642SPatrisious Haddad }
115*58dbd642SPatrisious Haddad 
del_sa_roce_rule(struct list_head * macsec_devices_list,struct mlx5_macsec_event_data * data)116*58dbd642SPatrisious Haddad static void del_sa_roce_rule(struct list_head *macsec_devices_list,
117*58dbd642SPatrisious Haddad 			     struct mlx5_macsec_event_data *data)
118*58dbd642SPatrisious Haddad {
119*58dbd642SPatrisious Haddad 	struct mlx5_macsec_device *macsec_device;
120*58dbd642SPatrisious Haddad 
121*58dbd642SPatrisious Haddad 	macsec_device = get_macsec_device(data->macdev, macsec_devices_list);
122*58dbd642SPatrisious Haddad 	WARN_ON(!macsec_device);
123*58dbd642SPatrisious Haddad 
124*58dbd642SPatrisious Haddad 	mlx5_macsec_del_roce_sa_rules(data->fs_id, data->macsec_fs,
125*58dbd642SPatrisious Haddad 				      &macsec_device->tx_rules_list,
126*58dbd642SPatrisious Haddad 				      &macsec_device->rx_rules_list, data->is_tx);
127*58dbd642SPatrisious Haddad }
128*58dbd642SPatrisious Haddad 
macsec_event(struct notifier_block * nb,unsigned long event,void * data)129*58dbd642SPatrisious Haddad static int macsec_event(struct notifier_block *nb, unsigned long event, void *data)
130*58dbd642SPatrisious Haddad {
131*58dbd642SPatrisious Haddad 	struct mlx5_macsec *macsec = container_of(nb, struct mlx5_macsec, blocking_events_nb);
132*58dbd642SPatrisious Haddad 
133*58dbd642SPatrisious Haddad 	mutex_lock(&macsec->lock);
134*58dbd642SPatrisious Haddad 	switch (event) {
135*58dbd642SPatrisious Haddad 	case MLX5_DRIVER_EVENT_MACSEC_SA_ADDED:
136*58dbd642SPatrisious Haddad 		handle_macsec_gids(&macsec->macsec_devices_list, data);
137*58dbd642SPatrisious Haddad 		break;
138*58dbd642SPatrisious Haddad 	case MLX5_DRIVER_EVENT_MACSEC_SA_DELETED:
139*58dbd642SPatrisious Haddad 		del_sa_roce_rule(&macsec->macsec_devices_list, data);
140*58dbd642SPatrisious Haddad 		break;
141*58dbd642SPatrisious Haddad 	default:
142*58dbd642SPatrisious Haddad 		mutex_unlock(&macsec->lock);
143*58dbd642SPatrisious Haddad 		return NOTIFY_DONE;
144*58dbd642SPatrisious Haddad 	}
145*58dbd642SPatrisious Haddad 	mutex_unlock(&macsec->lock);
146*58dbd642SPatrisious Haddad 	return NOTIFY_OK;
147*58dbd642SPatrisious Haddad }
148*58dbd642SPatrisious Haddad 
mlx5r_macsec_event_register(struct mlx5_ib_dev * dev)149*58dbd642SPatrisious Haddad void mlx5r_macsec_event_register(struct mlx5_ib_dev *dev)
150*58dbd642SPatrisious Haddad {
151*58dbd642SPatrisious Haddad 	if (!mlx5_is_macsec_roce_supported(dev->mdev)) {
152*58dbd642SPatrisious Haddad 		mlx5_ib_dbg(dev, "RoCE MACsec not supported due to capabilities\n");
153*58dbd642SPatrisious Haddad 		return;
154*58dbd642SPatrisious Haddad 	}
155*58dbd642SPatrisious Haddad 
156*58dbd642SPatrisious Haddad 	dev->macsec.blocking_events_nb.notifier_call = macsec_event;
157*58dbd642SPatrisious Haddad 	blocking_notifier_chain_register(&dev->mdev->macsec_nh,
158*58dbd642SPatrisious Haddad 					 &dev->macsec.blocking_events_nb);
159*58dbd642SPatrisious Haddad }
160*58dbd642SPatrisious Haddad 
mlx5r_macsec_event_unregister(struct mlx5_ib_dev * dev)161*58dbd642SPatrisious Haddad void mlx5r_macsec_event_unregister(struct mlx5_ib_dev *dev)
162*58dbd642SPatrisious Haddad {
163*58dbd642SPatrisious Haddad 	if (!mlx5_is_macsec_roce_supported(dev->mdev)) {
164*58dbd642SPatrisious Haddad 		mlx5_ib_dbg(dev, "RoCE MACsec not supported due to capabilities\n");
165*58dbd642SPatrisious Haddad 		return;
166*58dbd642SPatrisious Haddad 	}
167*58dbd642SPatrisious Haddad 
168*58dbd642SPatrisious Haddad 	blocking_notifier_chain_unregister(&dev->mdev->macsec_nh,
169*58dbd642SPatrisious Haddad 					   &dev->macsec.blocking_events_nb);
170*58dbd642SPatrisious Haddad }
171*58dbd642SPatrisious Haddad 
mlx5r_macsec_init_gids_and_devlist(struct mlx5_ib_dev * dev)172*58dbd642SPatrisious Haddad int mlx5r_macsec_init_gids_and_devlist(struct mlx5_ib_dev *dev)
173758ce14aSPatrisious Haddad {
174758ce14aSPatrisious Haddad 	int i, j, max_gids;
175758ce14aSPatrisious Haddad 
176758ce14aSPatrisious Haddad 	if (!mlx5_is_macsec_roce_supported(dev->mdev)) {
177758ce14aSPatrisious Haddad 		mlx5_ib_dbg(dev, "RoCE MACsec not supported due to capabilities\n");
178758ce14aSPatrisious Haddad 		return 0;
179758ce14aSPatrisious Haddad 	}
180758ce14aSPatrisious Haddad 
181758ce14aSPatrisious Haddad 	max_gids = MLX5_CAP_ROCE(dev->mdev, roce_address_table_size);
182758ce14aSPatrisious Haddad 	for (i = 0; i < dev->num_ports; i++) {
183758ce14aSPatrisious Haddad 		dev->port[i].reserved_gids = kcalloc(max_gids,
184758ce14aSPatrisious Haddad 						     sizeof(*dev->port[i].reserved_gids),
185758ce14aSPatrisious Haddad 						     GFP_KERNEL);
186758ce14aSPatrisious Haddad 		if (!dev->port[i].reserved_gids)
187758ce14aSPatrisious Haddad 			goto err;
188758ce14aSPatrisious Haddad 
189758ce14aSPatrisious Haddad 		for (j = 0; j < max_gids; j++)
190758ce14aSPatrisious Haddad 			dev->port[i].reserved_gids[j].macsec_index = -1;
191758ce14aSPatrisious Haddad 	}
192758ce14aSPatrisious Haddad 
193*58dbd642SPatrisious Haddad 	INIT_LIST_HEAD(&dev->macsec.macsec_devices_list);
194*58dbd642SPatrisious Haddad 	mutex_init(&dev->macsec.lock);
195*58dbd642SPatrisious Haddad 
196758ce14aSPatrisious Haddad 	return 0;
197758ce14aSPatrisious Haddad err:
198758ce14aSPatrisious Haddad 	while (i >= 0) {
199758ce14aSPatrisious Haddad 		kfree(dev->port[i].reserved_gids);
200758ce14aSPatrisious Haddad 		i--;
201758ce14aSPatrisious Haddad 	}
202758ce14aSPatrisious Haddad 	return -ENOMEM;
203758ce14aSPatrisious Haddad }
204758ce14aSPatrisious Haddad 
mlx5r_macsec_dealloc_gids(struct mlx5_ib_dev * dev)205758ce14aSPatrisious Haddad void mlx5r_macsec_dealloc_gids(struct mlx5_ib_dev *dev)
206758ce14aSPatrisious Haddad {
207758ce14aSPatrisious Haddad 	int i;
208758ce14aSPatrisious Haddad 
209758ce14aSPatrisious Haddad 	if (!mlx5_is_macsec_roce_supported(dev->mdev))
210758ce14aSPatrisious Haddad 		mlx5_ib_dbg(dev, "RoCE MACsec not supported due to capabilities\n");
211758ce14aSPatrisious Haddad 
212758ce14aSPatrisious Haddad 	for (i = 0; i < dev->num_ports; i++)
213758ce14aSPatrisious Haddad 		kfree(dev->port[i].reserved_gids);
214*58dbd642SPatrisious Haddad 
215*58dbd642SPatrisious Haddad 	mutex_destroy(&dev->macsec.lock);
216758ce14aSPatrisious Haddad }
217758ce14aSPatrisious Haddad 
mlx5r_add_gid_macsec_operations(const struct ib_gid_attr * attr)218758ce14aSPatrisious Haddad int mlx5r_add_gid_macsec_operations(const struct ib_gid_attr *attr)
219758ce14aSPatrisious Haddad {
220758ce14aSPatrisious Haddad 	struct mlx5_ib_dev *dev = to_mdev(attr->device);
221*58dbd642SPatrisious Haddad 	struct mlx5_macsec_device *macsec_device;
222758ce14aSPatrisious Haddad 	const struct ib_gid_attr *physical_gid;
223758ce14aSPatrisious Haddad 	struct mlx5_reserved_gids *mgids;
224758ce14aSPatrisious Haddad 	struct net_device *ndev;
225758ce14aSPatrisious Haddad 	int ret = 0;
226*58dbd642SPatrisious Haddad 	union {
227*58dbd642SPatrisious Haddad 		struct sockaddr_in  sockaddr_in;
228*58dbd642SPatrisious Haddad 		struct sockaddr_in6 sockaddr_in6;
229*58dbd642SPatrisious Haddad 	} addr;
230758ce14aSPatrisious Haddad 
231758ce14aSPatrisious Haddad 	if (attr->gid_type != IB_GID_TYPE_ROCE_UDP_ENCAP)
232758ce14aSPatrisious Haddad 		return 0;
233758ce14aSPatrisious Haddad 
234758ce14aSPatrisious Haddad 	if (!mlx5_is_macsec_roce_supported(dev->mdev)) {
235758ce14aSPatrisious Haddad 		mlx5_ib_dbg(dev, "RoCE MACsec not supported due to capabilities\n");
236758ce14aSPatrisious Haddad 		return 0;
237758ce14aSPatrisious Haddad 	}
238758ce14aSPatrisious Haddad 
239758ce14aSPatrisious Haddad 	rcu_read_lock();
240758ce14aSPatrisious Haddad 	ndev = rcu_dereference(attr->ndev);
241758ce14aSPatrisious Haddad 	if (!ndev) {
242758ce14aSPatrisious Haddad 		rcu_read_unlock();
243758ce14aSPatrisious Haddad 		return -ENODEV;
244758ce14aSPatrisious Haddad 	}
245758ce14aSPatrisious Haddad 
246758ce14aSPatrisious Haddad 	if (!netif_is_macsec(ndev) || !macsec_netdev_is_offloaded(ndev)) {
247758ce14aSPatrisious Haddad 		rcu_read_unlock();
248758ce14aSPatrisious Haddad 		return 0;
249758ce14aSPatrisious Haddad 	}
250*58dbd642SPatrisious Haddad 	dev_hold(ndev);
251758ce14aSPatrisious Haddad 	rcu_read_unlock();
252758ce14aSPatrisious Haddad 
253*58dbd642SPatrisious Haddad 	mutex_lock(&dev->macsec.lock);
254*58dbd642SPatrisious Haddad 	macsec_device = get_macsec_device(ndev, &dev->macsec.macsec_devices_list);
255*58dbd642SPatrisious Haddad 	if (!macsec_device) {
256*58dbd642SPatrisious Haddad 		ret = -ENOMEM;
257*58dbd642SPatrisious Haddad 		goto dev_err;
258*58dbd642SPatrisious Haddad 	}
259*58dbd642SPatrisious Haddad 
260758ce14aSPatrisious Haddad 	physical_gid = rdma_find_gid(attr->device, &attr->gid,
261758ce14aSPatrisious Haddad 				     attr->gid_type, NULL);
262*58dbd642SPatrisious Haddad 	if (!IS_ERR(physical_gid)) {
263758ce14aSPatrisious Haddad 		ret = set_roce_addr(to_mdev(physical_gid->device),
264758ce14aSPatrisious Haddad 				    physical_gid->port_num,
265758ce14aSPatrisious Haddad 				    physical_gid->index, NULL,
266758ce14aSPatrisious Haddad 				    physical_gid);
267758ce14aSPatrisious Haddad 		if (ret)
268758ce14aSPatrisious Haddad 			goto gid_err;
269758ce14aSPatrisious Haddad 
270758ce14aSPatrisious Haddad 		mgids = &dev->port[attr->port_num - 1].reserved_gids[physical_gid->index];
271758ce14aSPatrisious Haddad 		mgids->macsec_index = attr->index;
272758ce14aSPatrisious Haddad 		mgids->physical_gid = physical_gid;
273*58dbd642SPatrisious Haddad 	}
274758ce14aSPatrisious Haddad 
275*58dbd642SPatrisious Haddad 	/* Proceed with adding steering rules, regardless if there was gid ambiguity or not.*/
276*58dbd642SPatrisious Haddad 	rdma_gid2ip((struct sockaddr *)&addr, &attr->gid);
277*58dbd642SPatrisious Haddad 	ret = mlx5_macsec_add_roce_rule(ndev, (struct sockaddr *)&addr, attr->index,
278*58dbd642SPatrisious Haddad 					&macsec_device->tx_rules_list,
279*58dbd642SPatrisious Haddad 					&macsec_device->rx_rules_list, dev->mdev->macsec_fs);
280*58dbd642SPatrisious Haddad 	if (ret && !IS_ERR(physical_gid))
281*58dbd642SPatrisious Haddad 		goto rule_err;
282758ce14aSPatrisious Haddad 
283*58dbd642SPatrisious Haddad 	mlx5_macsec_save_roce_gid(macsec_device, (struct sockaddr *)&addr, attr->index);
284*58dbd642SPatrisious Haddad 
285*58dbd642SPatrisious Haddad 	dev_put(ndev);
286*58dbd642SPatrisious Haddad 	mutex_unlock(&dev->macsec.lock);
287*58dbd642SPatrisious Haddad 	return ret;
288*58dbd642SPatrisious Haddad 
289*58dbd642SPatrisious Haddad rule_err:
290*58dbd642SPatrisious Haddad 	set_roce_addr(to_mdev(physical_gid->device), physical_gid->port_num,
291*58dbd642SPatrisious Haddad 		      physical_gid->index, &physical_gid->gid, physical_gid);
292*58dbd642SPatrisious Haddad 	mgids->macsec_index = -1;
293758ce14aSPatrisious Haddad gid_err:
294758ce14aSPatrisious Haddad 	rdma_put_gid_attr(physical_gid);
295*58dbd642SPatrisious Haddad 	cleanup_macsec_device(macsec_device);
296*58dbd642SPatrisious Haddad dev_err:
297*58dbd642SPatrisious Haddad 	dev_put(ndev);
298*58dbd642SPatrisious Haddad 	mutex_unlock(&dev->macsec.lock);
299758ce14aSPatrisious Haddad 	return ret;
300758ce14aSPatrisious Haddad }
301758ce14aSPatrisious Haddad 
mlx5r_del_gid_macsec_operations(const struct ib_gid_attr * attr)302758ce14aSPatrisious Haddad void mlx5r_del_gid_macsec_operations(const struct ib_gid_attr *attr)
303758ce14aSPatrisious Haddad {
304758ce14aSPatrisious Haddad 	struct mlx5_ib_dev *dev = to_mdev(attr->device);
305*58dbd642SPatrisious Haddad 	struct mlx5_macsec_device *macsec_device;
306758ce14aSPatrisious Haddad 	struct mlx5_reserved_gids *mgids;
307758ce14aSPatrisious Haddad 	struct net_device *ndev;
308758ce14aSPatrisious Haddad 	int i, max_gids;
309758ce14aSPatrisious Haddad 
310758ce14aSPatrisious Haddad 	if (attr->gid_type != IB_GID_TYPE_ROCE_UDP_ENCAP)
311758ce14aSPatrisious Haddad 		return;
312758ce14aSPatrisious Haddad 
313758ce14aSPatrisious Haddad 	if (!mlx5_is_macsec_roce_supported(dev->mdev)) {
314758ce14aSPatrisious Haddad 		mlx5_ib_dbg(dev, "RoCE MACsec not supported due to capabilities\n");
315758ce14aSPatrisious Haddad 		return;
316758ce14aSPatrisious Haddad 	}
317758ce14aSPatrisious Haddad 
318758ce14aSPatrisious Haddad 	mgids = &dev->port[attr->port_num - 1].reserved_gids[attr->index];
319758ce14aSPatrisious Haddad 	if (mgids->macsec_index != -1) { /* Checking if physical gid has ambiguous IP */
320758ce14aSPatrisious Haddad 		rdma_put_gid_attr(mgids->physical_gid);
321758ce14aSPatrisious Haddad 		mgids->macsec_index = -1;
322758ce14aSPatrisious Haddad 		return;
323758ce14aSPatrisious Haddad 	}
324758ce14aSPatrisious Haddad 
325758ce14aSPatrisious Haddad 	rcu_read_lock();
326758ce14aSPatrisious Haddad 	ndev = rcu_dereference(attr->ndev);
327758ce14aSPatrisious Haddad 	if (!ndev) {
328758ce14aSPatrisious Haddad 		rcu_read_unlock();
329758ce14aSPatrisious Haddad 		return;
330758ce14aSPatrisious Haddad 	}
331758ce14aSPatrisious Haddad 
332758ce14aSPatrisious Haddad 	if (!netif_is_macsec(ndev) || !macsec_netdev_is_offloaded(ndev)) {
333758ce14aSPatrisious Haddad 		rcu_read_unlock();
334758ce14aSPatrisious Haddad 		return;
335758ce14aSPatrisious Haddad 	}
336*58dbd642SPatrisious Haddad 	dev_hold(ndev);
337758ce14aSPatrisious Haddad 	rcu_read_unlock();
338758ce14aSPatrisious Haddad 
339*58dbd642SPatrisious Haddad 	mutex_lock(&dev->macsec.lock);
340758ce14aSPatrisious Haddad 	max_gids = MLX5_CAP_ROCE(dev->mdev, roce_address_table_size);
341758ce14aSPatrisious Haddad 	for (i = 0; i < max_gids; i++) { /* Checking if macsec gid has ambiguous IP */
342758ce14aSPatrisious Haddad 		mgids = &dev->port[attr->port_num - 1].reserved_gids[i];
343758ce14aSPatrisious Haddad 		if (mgids->macsec_index == attr->index) {
344758ce14aSPatrisious Haddad 			const struct ib_gid_attr *physical_gid = mgids->physical_gid;
345758ce14aSPatrisious Haddad 
346758ce14aSPatrisious Haddad 			set_roce_addr(to_mdev(physical_gid->device),
347758ce14aSPatrisious Haddad 				      physical_gid->port_num,
348758ce14aSPatrisious Haddad 				      physical_gid->index,
349758ce14aSPatrisious Haddad 				      &physical_gid->gid, physical_gid);
350758ce14aSPatrisious Haddad 
351758ce14aSPatrisious Haddad 			rdma_put_gid_attr(physical_gid);
352758ce14aSPatrisious Haddad 			mgids->macsec_index = -1;
353758ce14aSPatrisious Haddad 			break;
354758ce14aSPatrisious Haddad 		}
355758ce14aSPatrisious Haddad 	}
356*58dbd642SPatrisious Haddad 	macsec_device = get_macsec_device(ndev, &dev->macsec.macsec_devices_list);
357*58dbd642SPatrisious Haddad 	mlx5_macsec_del_roce_rule(attr->index, dev->mdev->macsec_fs,
358*58dbd642SPatrisious Haddad 				  &macsec_device->tx_rules_list, &macsec_device->rx_rules_list);
359*58dbd642SPatrisious Haddad 	mlx5_macsec_del_roce_gid(macsec_device, attr->index);
360*58dbd642SPatrisious Haddad 	cleanup_macsec_device(macsec_device);
361*58dbd642SPatrisious Haddad 
362*58dbd642SPatrisious Haddad 	dev_put(ndev);
363*58dbd642SPatrisious Haddad 	mutex_unlock(&dev->macsec.lock);
364758ce14aSPatrisious Haddad }
365