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>
2017-08-30 17:23:11 +08:00
# include <linux/pci.h>
2018-03-14 14:39:42 -06:00
# include <uapi/rdma/hns-abi.h>
2016-07-21 19:06:38 +08:00
# include "hns_roce_device.h"
static int hns_roce_pd_alloc ( struct hns_roce_dev * hr_dev , unsigned long * pdn )
{
2018-08-09 22:00:47 +03:00
return hns_roce_bitmap_alloc ( & hr_dev - > pd_bitmap , pdn ) ? - ENOMEM : 0 ;
2016-07-21 19:06:38 +08:00
}
static void hns_roce_pd_free ( struct hns_roce_dev * hr_dev , unsigned long pdn )
{
2016-11-23 19:41:07 +00:00
hns_roce_bitmap_free ( & hr_dev - > pd_bitmap , pdn , BITMAP_NO_RR ) ;
2016-07-21 19:06:38 +08:00
}
int hns_roce_init_pd_table ( struct hns_roce_dev * hr_dev )
{
return hns_roce_bitmap_init ( & hr_dev - > pd_bitmap , hr_dev - > caps . num_pds ,
hr_dev - > caps . num_pds - 1 ,
hr_dev - > caps . reserved_pds , 0 ) ;
}
void hns_roce_cleanup_pd_table ( struct hns_roce_dev * hr_dev )
{
hns_roce_bitmap_cleanup ( & hr_dev - > pd_bitmap ) ;
}
2019-03-31 19:10:07 +03:00
int hns_roce_alloc_pd ( struct ib_pd * ibpd , struct ib_udata * udata )
2016-07-21 19:06:38 +08:00
{
2019-02-03 14:55:51 +02:00
struct ib_device * ib_dev = ibpd - > device ;
2016-07-21 19:06:38 +08:00
struct hns_roce_dev * hr_dev = to_hr_dev ( ib_dev ) ;
2017-08-30 17:23:02 +08:00
struct device * dev = hr_dev - > dev ;
2019-02-03 14:55:51 +02:00
struct hns_roce_pd * pd = to_hr_pd ( ibpd ) ;
2016-07-21 19:06:38 +08:00
int ret ;
ret = hns_roce_pd_alloc ( to_hr_dev ( ib_dev ) , & pd - > pdn ) ;
if ( ret ) {
dev_err ( dev , " [alloc_pd]hns_roce_pd_alloc failed! \n " ) ;
2019-02-03 14:55:51 +02:00
return ret ;
2016-07-21 19:06:38 +08:00
}
2019-03-31 19:10:07 +03:00
if ( udata ) {
2018-03-14 14:39:42 -06:00
struct hns_roce_ib_alloc_pd_resp uresp = { . pdn = pd - > pdn } ;
if ( ib_copy_to_udata ( udata , & uresp , sizeof ( uresp ) ) ) {
2016-07-21 19:06:38 +08:00
hns_roce_pd_free ( to_hr_dev ( ib_dev ) , pd - > pdn ) ;
dev_err ( dev , " [alloc_pd]ib_copy_to_udata failed! \n " ) ;
2019-02-03 14:55:51 +02:00
return - EFAULT ;
2016-07-21 19:06:38 +08:00
}
}
2019-02-03 14:55:51 +02:00
return 0 ;
2016-07-21 19:06:38 +08:00
}
2017-08-30 17:22:59 +08:00
EXPORT_SYMBOL_GPL ( hns_roce_alloc_pd ) ;
2016-07-21 19:06:38 +08:00
2019-03-31 19:10:05 +03:00
void hns_roce_dealloc_pd ( struct ib_pd * pd , struct ib_udata * udata )
2016-07-21 19:06:38 +08:00
{
hns_roce_pd_free ( to_hr_dev ( pd - > device ) , to_hr_pd ( pd ) - > pdn ) ;
}
2017-08-30 17:22:59 +08:00
EXPORT_SYMBOL_GPL ( hns_roce_dealloc_pd ) ;
2016-07-21 19:06:38 +08:00
int hns_roce_uar_alloc ( struct hns_roce_dev * hr_dev , struct hns_roce_uar * uar )
{
struct resource * res ;
int ret = 0 ;
/* Using bitmap to manager UAR index */
2018-05-23 18:16:27 +08:00
ret = hns_roce_bitmap_alloc ( & hr_dev - > uar_table . bitmap , & uar - > logic_idx ) ;
2016-07-21 19:06:38 +08:00
if ( ret = = - 1 )
return - ENOMEM ;
2018-05-23 18:16:27 +08:00
if ( uar - > logic_idx > 0 & & hr_dev - > caps . phy_num_uars > 1 )
uar - > index = ( uar - > logic_idx - 1 ) %
2016-09-15 23:48:11 +01:00
( hr_dev - > caps . phy_num_uars - 1 ) + 1 ;
2018-05-23 18:16:27 +08:00
else
uar - > index = 0 ;
2016-07-21 19:06:38 +08:00
2017-08-30 17:23:11 +08:00
if ( ! dev_is_pci ( hr_dev - > dev ) ) {
res = platform_get_resource ( hr_dev - > pdev , IORESOURCE_MEM , 0 ) ;
if ( ! res ) {
dev_err ( & hr_dev - > pdev - > dev , " memory resource not found! \n " ) ;
return - EINVAL ;
}
uar - > pfn = ( ( res - > start ) > > PAGE_SHIFT ) + uar - > index ;
} else {
uar - > pfn = ( ( pci_resource_start ( hr_dev - > pci_dev , 2 ) )
> > PAGE_SHIFT ) ;
2016-09-20 17:07:10 +01:00
}
2016-07-21 19:06:38 +08:00
return 0 ;
}
void hns_roce_uar_free ( struct hns_roce_dev * hr_dev , struct hns_roce_uar * uar )
{
2018-05-23 18:16:27 +08:00
hns_roce_bitmap_free ( & hr_dev - > uar_table . bitmap , uar - > logic_idx ,
2016-11-23 19:41:07 +00:00
BITMAP_NO_RR ) ;
2016-07-21 19:06:38 +08:00
}
int hns_roce_init_uar_table ( struct hns_roce_dev * hr_dev )
{
return hns_roce_bitmap_init ( & hr_dev - > uar_table . bitmap ,
hr_dev - > caps . num_uars ,
hr_dev - > caps . num_uars - 1 ,
hr_dev - > caps . reserved_uars , 0 ) ;
}
void hns_roce_cleanup_uar_table ( struct hns_roce_dev * hr_dev )
{
hns_roce_bitmap_cleanup ( & hr_dev - > uar_table . bitmap ) ;
}