1 // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) 2 /* 3 * Copyright(c) 2020 Intel Corporation. 4 * 5 */ 6 7 /* 8 * This file contains HFI1 support for ipoib functionality 9 */ 10 11 #include "ipoib.h" 12 #include "hfi.h" 13 14 static u32 qpn_from_mac(u8 *mac_arr) 15 { 16 return (u32)mac_arr[1] << 16 | mac_arr[2] << 8 | mac_arr[3]; 17 } 18 19 static int hfi1_ipoib_dev_init(struct net_device *dev) 20 { 21 struct hfi1_ipoib_dev_priv *priv = hfi1_ipoib_priv(dev); 22 int ret; 23 24 priv->netstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); 25 26 ret = priv->netdev_ops->ndo_init(dev); 27 if (ret) 28 return ret; 29 30 ret = hfi1_netdev_add_data(priv->dd, 31 qpn_from_mac(priv->netdev->dev_addr), 32 dev); 33 if (ret < 0) { 34 priv->netdev_ops->ndo_uninit(dev); 35 return ret; 36 } 37 38 return 0; 39 } 40 41 static void hfi1_ipoib_dev_uninit(struct net_device *dev) 42 { 43 struct hfi1_ipoib_dev_priv *priv = hfi1_ipoib_priv(dev); 44 45 hfi1_netdev_remove_data(priv->dd, qpn_from_mac(priv->netdev->dev_addr)); 46 47 priv->netdev_ops->ndo_uninit(dev); 48 } 49 50 static int hfi1_ipoib_dev_open(struct net_device *dev) 51 { 52 struct hfi1_ipoib_dev_priv *priv = hfi1_ipoib_priv(dev); 53 int ret; 54 55 ret = priv->netdev_ops->ndo_open(dev); 56 if (!ret) { 57 struct hfi1_ibport *ibp = to_iport(priv->device, 58 priv->port_num); 59 struct rvt_qp *qp; 60 u32 qpn = qpn_from_mac(priv->netdev->dev_addr); 61 62 rcu_read_lock(); 63 qp = rvt_lookup_qpn(ib_to_rvt(priv->device), &ibp->rvp, qpn); 64 if (!qp) { 65 rcu_read_unlock(); 66 priv->netdev_ops->ndo_stop(dev); 67 return -EINVAL; 68 } 69 rvt_get_qp(qp); 70 priv->qp = qp; 71 rcu_read_unlock(); 72 73 hfi1_netdev_enable_queues(priv->dd); 74 hfi1_ipoib_napi_tx_enable(dev); 75 } 76 77 return ret; 78 } 79 80 static int hfi1_ipoib_dev_stop(struct net_device *dev) 81 { 82 struct hfi1_ipoib_dev_priv *priv = hfi1_ipoib_priv(dev); 83 84 if (!priv->qp) 85 return 0; 86 87 hfi1_ipoib_napi_tx_disable(dev); 88 hfi1_netdev_disable_queues(priv->dd); 89 90 rvt_put_qp(priv->qp); 91 priv->qp = NULL; 92 93 return priv->netdev_ops->ndo_stop(dev); 94 } 95 96 static void hfi1_ipoib_dev_get_stats64(struct net_device *dev, 97 struct rtnl_link_stats64 *storage) 98 { 99 struct hfi1_ipoib_dev_priv *priv = hfi1_ipoib_priv(dev); 100 u64 rx_packets = 0ull; 101 u64 rx_bytes = 0ull; 102 u64 tx_packets = 0ull; 103 u64 tx_bytes = 0ull; 104 int i; 105 106 netdev_stats_to_stats64(storage, &dev->stats); 107 108 for_each_possible_cpu(i) { 109 const struct pcpu_sw_netstats *stats; 110 unsigned int start; 111 u64 trx_packets; 112 u64 trx_bytes; 113 u64 ttx_packets; 114 u64 ttx_bytes; 115 116 stats = per_cpu_ptr(priv->netstats, i); 117 do { 118 start = u64_stats_fetch_begin_irq(&stats->syncp); 119 trx_packets = stats->rx_packets; 120 trx_bytes = stats->rx_bytes; 121 ttx_packets = stats->tx_packets; 122 ttx_bytes = stats->tx_bytes; 123 } while (u64_stats_fetch_retry_irq(&stats->syncp, start)); 124 125 rx_packets += trx_packets; 126 rx_bytes += trx_bytes; 127 tx_packets += ttx_packets; 128 tx_bytes += ttx_bytes; 129 } 130 131 storage->rx_packets += rx_packets; 132 storage->rx_bytes += rx_bytes; 133 storage->tx_packets += tx_packets; 134 storage->tx_bytes += tx_bytes; 135 } 136 137 static const struct net_device_ops hfi1_ipoib_netdev_ops = { 138 .ndo_init = hfi1_ipoib_dev_init, 139 .ndo_uninit = hfi1_ipoib_dev_uninit, 140 .ndo_open = hfi1_ipoib_dev_open, 141 .ndo_stop = hfi1_ipoib_dev_stop, 142 .ndo_get_stats64 = hfi1_ipoib_dev_get_stats64, 143 }; 144 145 static int hfi1_ipoib_send(struct net_device *dev, 146 struct sk_buff *skb, 147 struct ib_ah *address, 148 u32 dqpn) 149 { 150 return hfi1_ipoib_send_dma(dev, skb, address, dqpn); 151 } 152 153 static int hfi1_ipoib_mcast_attach(struct net_device *dev, 154 struct ib_device *device, 155 union ib_gid *mgid, 156 u16 mlid, 157 int set_qkey, 158 u32 qkey) 159 { 160 struct hfi1_ipoib_dev_priv *priv = hfi1_ipoib_priv(dev); 161 u32 qpn = (u32)qpn_from_mac(priv->netdev->dev_addr); 162 struct hfi1_ibport *ibp = to_iport(priv->device, priv->port_num); 163 struct rvt_qp *qp; 164 int ret = -EINVAL; 165 166 rcu_read_lock(); 167 168 qp = rvt_lookup_qpn(ib_to_rvt(priv->device), &ibp->rvp, qpn); 169 if (qp) { 170 rvt_get_qp(qp); 171 rcu_read_unlock(); 172 if (set_qkey) 173 priv->qkey = qkey; 174 175 /* attach QP to multicast group */ 176 ret = ib_attach_mcast(&qp->ibqp, mgid, mlid); 177 rvt_put_qp(qp); 178 } else { 179 rcu_read_unlock(); 180 } 181 182 return ret; 183 } 184 185 static int hfi1_ipoib_mcast_detach(struct net_device *dev, 186 struct ib_device *device, 187 union ib_gid *mgid, 188 u16 mlid) 189 { 190 struct hfi1_ipoib_dev_priv *priv = hfi1_ipoib_priv(dev); 191 u32 qpn = (u32)qpn_from_mac(priv->netdev->dev_addr); 192 struct hfi1_ibport *ibp = to_iport(priv->device, priv->port_num); 193 struct rvt_qp *qp; 194 int ret = -EINVAL; 195 196 rcu_read_lock(); 197 198 qp = rvt_lookup_qpn(ib_to_rvt(priv->device), &ibp->rvp, qpn); 199 if (qp) { 200 rvt_get_qp(qp); 201 rcu_read_unlock(); 202 ret = ib_detach_mcast(&qp->ibqp, mgid, mlid); 203 rvt_put_qp(qp); 204 } else { 205 rcu_read_unlock(); 206 } 207 return ret; 208 } 209 210 static void hfi1_ipoib_netdev_dtor(struct net_device *dev) 211 { 212 struct hfi1_ipoib_dev_priv *priv = hfi1_ipoib_priv(dev); 213 214 hfi1_ipoib_txreq_deinit(priv); 215 hfi1_ipoib_rxq_deinit(priv->netdev); 216 217 free_percpu(priv->netstats); 218 } 219 220 static void hfi1_ipoib_free_rdma_netdev(struct net_device *dev) 221 { 222 hfi1_ipoib_netdev_dtor(dev); 223 free_netdev(dev); 224 } 225 226 static void hfi1_ipoib_set_id(struct net_device *dev, int id) 227 { 228 struct hfi1_ipoib_dev_priv *priv = hfi1_ipoib_priv(dev); 229 230 priv->pkey_index = (u16)id; 231 ib_query_pkey(priv->device, 232 priv->port_num, 233 priv->pkey_index, 234 &priv->pkey); 235 } 236 237 static int hfi1_ipoib_setup_rn(struct ib_device *device, 238 u8 port_num, 239 struct net_device *netdev, 240 void *param) 241 { 242 struct hfi1_devdata *dd = dd_from_ibdev(device); 243 struct rdma_netdev *rn = netdev_priv(netdev); 244 struct hfi1_ipoib_dev_priv *priv; 245 int rc; 246 247 rn->send = hfi1_ipoib_send; 248 rn->attach_mcast = hfi1_ipoib_mcast_attach; 249 rn->detach_mcast = hfi1_ipoib_mcast_detach; 250 rn->set_id = hfi1_ipoib_set_id; 251 rn->hca = device; 252 rn->port_num = port_num; 253 rn->mtu = netdev->mtu; 254 255 priv = hfi1_ipoib_priv(netdev); 256 priv->dd = dd; 257 priv->netdev = netdev; 258 priv->device = device; 259 priv->port_num = port_num; 260 priv->netdev_ops = netdev->netdev_ops; 261 262 netdev->netdev_ops = &hfi1_ipoib_netdev_ops; 263 264 ib_query_pkey(device, port_num, priv->pkey_index, &priv->pkey); 265 266 rc = hfi1_ipoib_txreq_init(priv); 267 if (rc) { 268 dd_dev_err(dd, "IPoIB netdev TX init - failed(%d)\n", rc); 269 hfi1_ipoib_free_rdma_netdev(netdev); 270 return rc; 271 } 272 273 rc = hfi1_ipoib_rxq_init(netdev); 274 if (rc) { 275 dd_dev_err(dd, "IPoIB netdev RX init - failed(%d)\n", rc); 276 hfi1_ipoib_free_rdma_netdev(netdev); 277 return rc; 278 } 279 280 netdev->priv_destructor = hfi1_ipoib_netdev_dtor; 281 netdev->needs_free_netdev = true; 282 283 return 0; 284 } 285 286 int hfi1_ipoib_rn_get_params(struct ib_device *device, 287 u8 port_num, 288 enum rdma_netdev_t type, 289 struct rdma_netdev_alloc_params *params) 290 { 291 struct hfi1_devdata *dd = dd_from_ibdev(device); 292 293 if (type != RDMA_NETDEV_IPOIB) 294 return -EOPNOTSUPP; 295 296 if (!HFI1_CAP_IS_KSET(AIP) || !dd->num_netdev_contexts) 297 return -EOPNOTSUPP; 298 299 if (!port_num || port_num > dd->num_pports) 300 return -EINVAL; 301 302 params->sizeof_priv = sizeof(struct hfi1_ipoib_rdma_netdev); 303 params->txqs = dd->num_sdma; 304 params->rxqs = dd->num_netdev_contexts; 305 params->param = NULL; 306 params->initialize_rdma_netdev = hfi1_ipoib_setup_rn; 307 308 return 0; 309 } 310