xref: /openbmc/linux/drivers/infiniband/hw/mlx5/macsec.c (revision 758ce14aee825f8f3ca8f76c9991c108094cae8b)
1*758ce14aSPatrisious Haddad // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2*758ce14aSPatrisious Haddad /* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. */
3*758ce14aSPatrisious Haddad 
4*758ce14aSPatrisious Haddad #include "macsec.h"
5*758ce14aSPatrisious Haddad 
6*758ce14aSPatrisious Haddad struct mlx5_reserved_gids {
7*758ce14aSPatrisious Haddad 	int macsec_index;
8*758ce14aSPatrisious Haddad 	const struct ib_gid_attr *physical_gid;
9*758ce14aSPatrisious Haddad };
10*758ce14aSPatrisious Haddad 
11*758ce14aSPatrisious Haddad int mlx5r_macsec_alloc_gids(struct mlx5_ib_dev *dev)
12*758ce14aSPatrisious Haddad {
13*758ce14aSPatrisious Haddad 	int i, j, max_gids;
14*758ce14aSPatrisious Haddad 
15*758ce14aSPatrisious Haddad 	if (!mlx5_is_macsec_roce_supported(dev->mdev)) {
16*758ce14aSPatrisious Haddad 		mlx5_ib_dbg(dev, "RoCE MACsec not supported due to capabilities\n");
17*758ce14aSPatrisious Haddad 		return 0;
18*758ce14aSPatrisious Haddad 	}
19*758ce14aSPatrisious Haddad 
20*758ce14aSPatrisious Haddad 	max_gids = MLX5_CAP_ROCE(dev->mdev, roce_address_table_size);
21*758ce14aSPatrisious Haddad 	for (i = 0; i < dev->num_ports; i++) {
22*758ce14aSPatrisious Haddad 		dev->port[i].reserved_gids = kcalloc(max_gids,
23*758ce14aSPatrisious Haddad 						     sizeof(*dev->port[i].reserved_gids),
24*758ce14aSPatrisious Haddad 						     GFP_KERNEL);
25*758ce14aSPatrisious Haddad 		if (!dev->port[i].reserved_gids)
26*758ce14aSPatrisious Haddad 			goto err;
27*758ce14aSPatrisious Haddad 
28*758ce14aSPatrisious Haddad 		for (j = 0; j < max_gids; j++)
29*758ce14aSPatrisious Haddad 			dev->port[i].reserved_gids[j].macsec_index = -1;
30*758ce14aSPatrisious Haddad 	}
31*758ce14aSPatrisious Haddad 
32*758ce14aSPatrisious Haddad 	return 0;
33*758ce14aSPatrisious Haddad err:
34*758ce14aSPatrisious Haddad 	while (i >= 0) {
35*758ce14aSPatrisious Haddad 		kfree(dev->port[i].reserved_gids);
36*758ce14aSPatrisious Haddad 		i--;
37*758ce14aSPatrisious Haddad 	}
38*758ce14aSPatrisious Haddad 	return -ENOMEM;
39*758ce14aSPatrisious Haddad }
40*758ce14aSPatrisious Haddad 
41*758ce14aSPatrisious Haddad void mlx5r_macsec_dealloc_gids(struct mlx5_ib_dev *dev)
42*758ce14aSPatrisious Haddad {
43*758ce14aSPatrisious Haddad 	int i;
44*758ce14aSPatrisious Haddad 
45*758ce14aSPatrisious Haddad 	if (!mlx5_is_macsec_roce_supported(dev->mdev))
46*758ce14aSPatrisious Haddad 		mlx5_ib_dbg(dev, "RoCE MACsec not supported due to capabilities\n");
47*758ce14aSPatrisious Haddad 
48*758ce14aSPatrisious Haddad 	for (i = 0; i < dev->num_ports; i++)
49*758ce14aSPatrisious Haddad 		kfree(dev->port[i].reserved_gids);
50*758ce14aSPatrisious Haddad }
51*758ce14aSPatrisious Haddad 
52*758ce14aSPatrisious Haddad int mlx5r_add_gid_macsec_operations(const struct ib_gid_attr *attr)
53*758ce14aSPatrisious Haddad {
54*758ce14aSPatrisious Haddad 	struct mlx5_ib_dev *dev = to_mdev(attr->device);
55*758ce14aSPatrisious Haddad 	const struct ib_gid_attr *physical_gid;
56*758ce14aSPatrisious Haddad 	struct mlx5_reserved_gids *mgids;
57*758ce14aSPatrisious Haddad 	struct net_device *ndev;
58*758ce14aSPatrisious Haddad 	int ret = 0;
59*758ce14aSPatrisious Haddad 
60*758ce14aSPatrisious Haddad 	if (attr->gid_type != IB_GID_TYPE_ROCE_UDP_ENCAP)
61*758ce14aSPatrisious Haddad 		return 0;
62*758ce14aSPatrisious Haddad 
63*758ce14aSPatrisious Haddad 	if (!mlx5_is_macsec_roce_supported(dev->mdev)) {
64*758ce14aSPatrisious Haddad 		mlx5_ib_dbg(dev, "RoCE MACsec not supported due to capabilities\n");
65*758ce14aSPatrisious Haddad 		return 0;
66*758ce14aSPatrisious Haddad 	}
67*758ce14aSPatrisious Haddad 
68*758ce14aSPatrisious Haddad 	rcu_read_lock();
69*758ce14aSPatrisious Haddad 	ndev = rcu_dereference(attr->ndev);
70*758ce14aSPatrisious Haddad 	if (!ndev) {
71*758ce14aSPatrisious Haddad 		rcu_read_unlock();
72*758ce14aSPatrisious Haddad 		return -ENODEV;
73*758ce14aSPatrisious Haddad 	}
74*758ce14aSPatrisious Haddad 
75*758ce14aSPatrisious Haddad 	if (!netif_is_macsec(ndev) || !macsec_netdev_is_offloaded(ndev)) {
76*758ce14aSPatrisious Haddad 		rcu_read_unlock();
77*758ce14aSPatrisious Haddad 		return 0;
78*758ce14aSPatrisious Haddad 	}
79*758ce14aSPatrisious Haddad 	rcu_read_unlock();
80*758ce14aSPatrisious Haddad 
81*758ce14aSPatrisious Haddad 	physical_gid = rdma_find_gid(attr->device, &attr->gid,
82*758ce14aSPatrisious Haddad 				     attr->gid_type, NULL);
83*758ce14aSPatrisious Haddad 	if (IS_ERR(physical_gid))
84*758ce14aSPatrisious Haddad 		return 0;
85*758ce14aSPatrisious Haddad 
86*758ce14aSPatrisious Haddad 	ret = set_roce_addr(to_mdev(physical_gid->device),
87*758ce14aSPatrisious Haddad 			    physical_gid->port_num,
88*758ce14aSPatrisious Haddad 			    physical_gid->index, NULL,
89*758ce14aSPatrisious Haddad 			    physical_gid);
90*758ce14aSPatrisious Haddad 	if (ret)
91*758ce14aSPatrisious Haddad 		goto gid_err;
92*758ce14aSPatrisious Haddad 
93*758ce14aSPatrisious Haddad 	mgids = &dev->port[attr->port_num - 1].reserved_gids[physical_gid->index];
94*758ce14aSPatrisious Haddad 	mgids->macsec_index = attr->index;
95*758ce14aSPatrisious Haddad 	mgids->physical_gid = physical_gid;
96*758ce14aSPatrisious Haddad 
97*758ce14aSPatrisious Haddad 	return 0;
98*758ce14aSPatrisious Haddad 
99*758ce14aSPatrisious Haddad gid_err:
100*758ce14aSPatrisious Haddad 	rdma_put_gid_attr(physical_gid);
101*758ce14aSPatrisious Haddad 	return ret;
102*758ce14aSPatrisious Haddad }
103*758ce14aSPatrisious Haddad 
104*758ce14aSPatrisious Haddad void mlx5r_del_gid_macsec_operations(const struct ib_gid_attr *attr)
105*758ce14aSPatrisious Haddad {
106*758ce14aSPatrisious Haddad 	struct mlx5_ib_dev *dev = to_mdev(attr->device);
107*758ce14aSPatrisious Haddad 	struct mlx5_reserved_gids *mgids;
108*758ce14aSPatrisious Haddad 	struct net_device *ndev;
109*758ce14aSPatrisious Haddad 	int i, max_gids;
110*758ce14aSPatrisious Haddad 
111*758ce14aSPatrisious Haddad 	if (attr->gid_type != IB_GID_TYPE_ROCE_UDP_ENCAP)
112*758ce14aSPatrisious Haddad 		return;
113*758ce14aSPatrisious Haddad 
114*758ce14aSPatrisious Haddad 	if (!mlx5_is_macsec_roce_supported(dev->mdev)) {
115*758ce14aSPatrisious Haddad 		mlx5_ib_dbg(dev, "RoCE MACsec not supported due to capabilities\n");
116*758ce14aSPatrisious Haddad 		return;
117*758ce14aSPatrisious Haddad 	}
118*758ce14aSPatrisious Haddad 
119*758ce14aSPatrisious Haddad 	mgids = &dev->port[attr->port_num - 1].reserved_gids[attr->index];
120*758ce14aSPatrisious Haddad 	if (mgids->macsec_index != -1) { /* Checking if physical gid has ambiguous IP */
121*758ce14aSPatrisious Haddad 		rdma_put_gid_attr(mgids->physical_gid);
122*758ce14aSPatrisious Haddad 		mgids->macsec_index = -1;
123*758ce14aSPatrisious Haddad 		return;
124*758ce14aSPatrisious Haddad 	}
125*758ce14aSPatrisious Haddad 
126*758ce14aSPatrisious Haddad 	rcu_read_lock();
127*758ce14aSPatrisious Haddad 	ndev = rcu_dereference(attr->ndev);
128*758ce14aSPatrisious Haddad 	if (!ndev) {
129*758ce14aSPatrisious Haddad 		rcu_read_unlock();
130*758ce14aSPatrisious Haddad 		return;
131*758ce14aSPatrisious Haddad 	}
132*758ce14aSPatrisious Haddad 
133*758ce14aSPatrisious Haddad 	if (!netif_is_macsec(ndev) || !macsec_netdev_is_offloaded(ndev)) {
134*758ce14aSPatrisious Haddad 		rcu_read_unlock();
135*758ce14aSPatrisious Haddad 		return;
136*758ce14aSPatrisious Haddad 	}
137*758ce14aSPatrisious Haddad 	rcu_read_unlock();
138*758ce14aSPatrisious Haddad 
139*758ce14aSPatrisious Haddad 	max_gids = MLX5_CAP_ROCE(dev->mdev, roce_address_table_size);
140*758ce14aSPatrisious Haddad 	for (i = 0; i < max_gids; i++) { /* Checking if macsec gid has ambiguous IP */
141*758ce14aSPatrisious Haddad 		mgids = &dev->port[attr->port_num - 1].reserved_gids[i];
142*758ce14aSPatrisious Haddad 		if (mgids->macsec_index == attr->index) {
143*758ce14aSPatrisious Haddad 			const struct ib_gid_attr *physical_gid = mgids->physical_gid;
144*758ce14aSPatrisious Haddad 
145*758ce14aSPatrisious Haddad 			set_roce_addr(to_mdev(physical_gid->device),
146*758ce14aSPatrisious Haddad 				      physical_gid->port_num,
147*758ce14aSPatrisious Haddad 				      physical_gid->index,
148*758ce14aSPatrisious Haddad 				      &physical_gid->gid, physical_gid);
149*758ce14aSPatrisious Haddad 
150*758ce14aSPatrisious Haddad 			rdma_put_gid_attr(physical_gid);
151*758ce14aSPatrisious Haddad 			mgids->macsec_index = -1;
152*758ce14aSPatrisious Haddad 			break;
153*758ce14aSPatrisious Haddad 		}
154*758ce14aSPatrisious Haddad 	}
155*758ce14aSPatrisious Haddad }
156