Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright (c) 2016 Hisilicon Limited.
0003  *
0004  * This software is available to you under a choice of one of two
0005  * licenses.  You may choose to be licensed under the terms of the GNU
0006  * General Public License (GPL) Version 2, available from the file
0007  * COPYING in the main directory of this source tree, or the
0008  * OpenIB.org BSD license below:
0009  *
0010  *     Redistribution and use in source and binary forms, with or
0011  *     without modification, are permitted provided that the following
0012  *     conditions are met:
0013  *
0014  *      - Redistributions of source code must retain the above
0015  *        copyright notice, this list of conditions and the following
0016  *        disclaimer.
0017  *
0018  *      - Redistributions in binary form must reproduce the above
0019  *        copyright notice, this list of conditions and the following
0020  *        disclaimer in the documentation and/or other materials
0021  *        provided with the distribution.
0022  *
0023  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
0024  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
0025  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
0026  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
0027  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
0028  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
0029  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
0030  * SOFTWARE.
0031  */
0032 
0033 #include <linux/pci.h>
0034 #include <rdma/ib_addr.h>
0035 #include <rdma/ib_cache.h>
0036 #include "hns_roce_device.h"
0037 
0038 static inline u16 get_ah_udp_sport(const struct rdma_ah_attr *ah_attr)
0039 {
0040     u32 fl = ah_attr->grh.flow_label;
0041     u16 sport;
0042 
0043     if (!fl)
0044         sport = get_random_u32() %
0045             (IB_ROCE_UDP_ENCAP_VALID_PORT_MAX + 1 -
0046              IB_ROCE_UDP_ENCAP_VALID_PORT_MIN) +
0047             IB_ROCE_UDP_ENCAP_VALID_PORT_MIN;
0048     else
0049         sport = rdma_flow_label_to_udp_sport(fl);
0050 
0051     return sport;
0052 }
0053 
0054 int hns_roce_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr,
0055                struct ib_udata *udata)
0056 {
0057     struct rdma_ah_attr *ah_attr = init_attr->ah_attr;
0058     const struct ib_global_route *grh = rdma_ah_read_grh(ah_attr);
0059     struct hns_roce_dev *hr_dev = to_hr_dev(ibah->device);
0060     struct hns_roce_ah *ah = to_hr_ah(ibah);
0061     int ret = 0;
0062 
0063     if (hr_dev->pci_dev->revision == PCI_REVISION_ID_HIP08 && udata)
0064         return -EOPNOTSUPP;
0065 
0066     ah->av.port = rdma_ah_get_port_num(ah_attr);
0067     ah->av.gid_index = grh->sgid_index;
0068 
0069     if (rdma_ah_get_static_rate(ah_attr))
0070         ah->av.stat_rate = IB_RATE_10_GBPS;
0071 
0072     ah->av.hop_limit = grh->hop_limit;
0073     ah->av.flowlabel = grh->flow_label;
0074     ah->av.udp_sport = get_ah_udp_sport(ah_attr);
0075     ah->av.sl = rdma_ah_get_sl(ah_attr);
0076     ah->av.tclass = get_tclass(grh);
0077 
0078     memcpy(ah->av.dgid, grh->dgid.raw, HNS_ROCE_GID_SIZE);
0079     memcpy(ah->av.mac, ah_attr->roce.dmac, ETH_ALEN);
0080 
0081     /* HIP08 needs to record vlan info in Address Vector */
0082     if (hr_dev->pci_dev->revision == PCI_REVISION_ID_HIP08) {
0083         ret = rdma_read_gid_l2_fields(ah_attr->grh.sgid_attr,
0084                           &ah->av.vlan_id, NULL);
0085         if (ret)
0086             return ret;
0087 
0088         ah->av.vlan_en = ah->av.vlan_id < VLAN_N_VID;
0089     }
0090 
0091     return ret;
0092 }
0093 
0094 int hns_roce_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr)
0095 {
0096     struct hns_roce_ah *ah = to_hr_ah(ibah);
0097 
0098     memset(ah_attr, 0, sizeof(*ah_attr));
0099 
0100     rdma_ah_set_sl(ah_attr, ah->av.sl);
0101     rdma_ah_set_port_num(ah_attr, ah->av.port);
0102     rdma_ah_set_static_rate(ah_attr, ah->av.stat_rate);
0103     rdma_ah_set_grh(ah_attr, NULL, ah->av.flowlabel,
0104             ah->av.gid_index, ah->av.hop_limit, ah->av.tclass);
0105     rdma_ah_set_dgid_raw(ah_attr, ah->av.dgid);
0106 
0107     return 0;
0108 }