2016-07-21 19:06:38 +08:00
/*
* Copyright ( c ) 2016 Hisilicon Limited .
*
* This software is available to you under a choice of one of two
* licenses . You may choose to be licensed under the terms of the GNU
* General Public License ( GPL ) Version 2 , available from the file
* COPYING in the main directory of this source tree , or the
* OpenIB . org BSD license below :
*
* Redistribution and use in source and binary forms , with or
* without modification , are permitted provided that the following
* conditions are met :
*
* - Redistributions of source code must retain the above
* copyright notice , this list of conditions and the following
* disclaimer .
*
* - Redistributions in binary form must reproduce the above
* copyright notice , this list of conditions and the following
* disclaimer in the documentation and / or other materials
* provided with the distribution .
*
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND ,
* EXPRESS OR IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY , FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT . IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER LIABILITY , WHETHER IN AN
* ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM , OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE .
*/
# include <linux/platform_device.h>
2020-11-16 19:33:22 +08:00
# include <linux/pci.h>
2016-07-21 19:06:38 +08:00
# include <rdma/ib_addr.h>
# include <rdma/ib_cache.h>
# include "hns_roce_device.h"
2020-08-21 17:31:29 +08:00
static inline u16 get_ah_udp_sport ( const struct rdma_ah_attr * ah_attr )
{
u32 fl = ah_attr - > grh . flow_label ;
u16 sport ;
if ( ! fl )
sport = get_random_u32 ( ) %
( IB_ROCE_UDP_ENCAP_VALID_PORT_MAX + 1 -
IB_ROCE_UDP_ENCAP_VALID_PORT_MIN ) +
IB_ROCE_UDP_ENCAP_VALID_PORT_MIN ;
else
sport = rdma_flow_label_to_udp_sport ( fl ) ;
return sport ;
}
2020-04-30 22:21:42 +03:00
int hns_roce_create_ah ( struct ib_ah * ibah , struct rdma_ah_init_attr * init_attr ,
struct ib_udata * udata )
2016-07-21 19:06:38 +08:00
{
2020-04-30 22:21:42 +03:00
struct rdma_ah_attr * ah_attr = init_attr - > ah_attr ;
2017-04-29 14:41:28 -04:00
const struct ib_global_route * grh = rdma_ah_read_grh ( ah_attr ) ;
2020-11-16 19:33:22 +08:00
struct hns_roce_dev * hr_dev = to_hr_dev ( ibah - > device ) ;
struct hns_roce_ah * ah = to_hr_ah ( ibah ) ;
int ret = 0 ;
2016-07-21 19:06:38 +08:00
2020-11-16 19:33:27 +08:00
if ( hr_dev - > pci_dev - > revision < = PCI_REVISION_ID_HIP08 & & udata )
return - EOPNOTSUPP ;
2019-08-21 21:14:30 +08:00
ah - > av . port = rdma_ah_get_port_num ( ah_attr ) ;
2017-04-29 14:41:28 -04:00
ah - > av . gid_index = grh - > sgid_index ;
2016-07-21 19:06:38 +08:00
2017-04-29 14:41:28 -04:00
if ( rdma_ah_get_static_rate ( ah_attr ) )
2016-07-21 19:06:38 +08:00
ah - > av . stat_rate = IB_RATE_10_GBPS ;
2020-11-16 19:33:23 +08:00
ah - > av . hop_limit = grh - > hop_limit ;
2020-08-21 17:31:29 +08:00
ah - > av . flowlabel = grh - > flow_label ;
ah - > av . udp_sport = get_ah_udp_sport ( ah_attr ) ;
2020-11-16 19:33:23 +08:00
ah - > av . sl = rdma_ah_get_sl ( ah_attr ) ;
2020-12-11 09:37:29 +08:00
ah - > av . tclass = get_tclass ( grh ) ;
2020-11-16 19:33:23 +08:00
memcpy ( ah - > av . dgid , grh - > dgid . raw , HNS_ROCE_GID_SIZE ) ;
memcpy ( ah - > av . mac , ah_attr - > roce . dmac , ETH_ALEN ) ;
2016-07-21 19:06:38 +08:00
2020-11-16 19:33:22 +08:00
/* HIP08 needs to record vlan info in Address Vector */
if ( hr_dev - > pci_dev - > revision < = PCI_REVISION_ID_HIP08 ) {
ret = rdma_read_gid_l2_fields ( ah_attr - > grh . sgid_attr ,
& ah - > av . vlan_id , NULL ) ;
if ( ret )
return ret ;
2020-12-11 09:37:30 +08:00
ah - > av . vlan_en = ah - > av . vlan_id < VLAN_N_VID ;
2020-11-16 19:33:22 +08:00
}
return ret ;
2016-07-21 19:06:38 +08:00
}
2017-04-29 14:41:18 -04:00
int hns_roce_query_ah ( struct ib_ah * ibah , struct rdma_ah_attr * ah_attr )
2016-07-21 19:06:38 +08:00
{
struct hns_roce_ah * ah = to_hr_ah ( ibah ) ;
memset ( ah_attr , 0 , sizeof ( * ah_attr ) ) ;
2019-08-21 21:14:30 +08:00
rdma_ah_set_sl ( ah_attr , ah - > av . sl ) ;
rdma_ah_set_port_num ( ah_attr , ah - > av . port ) ;
2017-04-29 14:41:28 -04:00
rdma_ah_set_static_rate ( ah_attr , ah - > av . stat_rate ) ;
2019-08-21 21:14:30 +08:00
rdma_ah_set_grh ( ah_attr , NULL , ah - > av . flowlabel ,
ah - > av . gid_index , ah - > av . hop_limit , ah - > av . tclass ) ;
2017-04-29 14:41:28 -04:00
rdma_ah_set_dgid_raw ( ah_attr , ah - > av . dgid ) ;
2016-07-21 19:06:38 +08:00
return 0 ;
}