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