3434#include <linux/acpi.h>
3535#include <linux/etherdevice.h>
3636#include <linux/of.h>
37+ #include <linux/of_platform.h>
3738#include <rdma/ib_umem.h>
3839#include "hns_roce_common.h"
3940#include "hns_roce_device.h"
@@ -3843,7 +3844,7 @@ int hns_roce_v1_destroy_cq(struct ib_cq *ibcq)
38433844
38443845struct hns_roce_v1_priv hr_v1_priv ;
38453846
3846- struct hns_roce_hw hns_roce_hw_v1 = {
3847+ static const struct hns_roce_hw hns_roce_hw_v1 = {
38473848 .reset = hns_roce_v1_reset ,
38483849 .hw_profile = hns_roce_v1_profile ,
38493850 .hw_init = hns_roce_v1_init ,
@@ -3865,3 +3866,244 @@ struct hns_roce_hw hns_roce_hw_v1 = {
38653866 .destroy_cq = hns_roce_v1_destroy_cq ,
38663867 .priv = & hr_v1_priv ,
38673868};
3869+
3870+ static const struct of_device_id hns_roce_of_match [] = {
3871+ { .compatible = "hisilicon,hns-roce-v1" , .data = & hns_roce_hw_v1 , },
3872+ {},
3873+ };
3874+ MODULE_DEVICE_TABLE (of , hns_roce_of_match );
3875+
3876+ static const struct acpi_device_id hns_roce_acpi_match [] = {
3877+ { "HISI00D1" , (kernel_ulong_t )& hns_roce_hw_v1 },
3878+ {},
3879+ };
3880+ MODULE_DEVICE_TABLE (acpi , hns_roce_acpi_match );
3881+
3882+ static int hns_roce_node_match (struct device * dev , void * fwnode )
3883+ {
3884+ return dev -> fwnode == fwnode ;
3885+ }
3886+
3887+ static struct
3888+ platform_device * hns_roce_find_pdev (struct fwnode_handle * fwnode )
3889+ {
3890+ struct device * dev ;
3891+
3892+ /* get the 'device' corresponding to the matching 'fwnode' */
3893+ dev = bus_find_device (& platform_bus_type , NULL ,
3894+ fwnode , hns_roce_node_match );
3895+ /* get the platform device */
3896+ return dev ? to_platform_device (dev ) : NULL ;
3897+ }
3898+
3899+ static int hns_roce_get_cfg (struct hns_roce_dev * hr_dev )
3900+ {
3901+ struct device * dev = & hr_dev -> pdev -> dev ;
3902+ struct platform_device * pdev = NULL ;
3903+ struct net_device * netdev = NULL ;
3904+ struct device_node * net_node ;
3905+ struct resource * res ;
3906+ int port_cnt = 0 ;
3907+ u8 phy_port ;
3908+ int ret ;
3909+ int i ;
3910+
3911+ /* check if we are compatible with the underlying SoC */
3912+ if (dev_of_node (dev )) {
3913+ const struct of_device_id * of_id ;
3914+
3915+ of_id = of_match_node (hns_roce_of_match , dev -> of_node );
3916+ if (!of_id ) {
3917+ dev_err (dev , "device is not compatible!\n" );
3918+ return - ENXIO ;
3919+ }
3920+ hr_dev -> hw = (const struct hns_roce_hw * )of_id -> data ;
3921+ if (!hr_dev -> hw ) {
3922+ dev_err (dev , "couldn't get H/W specific DT data!\n" );
3923+ return - ENXIO ;
3924+ }
3925+ } else if (is_acpi_device_node (dev -> fwnode )) {
3926+ const struct acpi_device_id * acpi_id ;
3927+
3928+ acpi_id = acpi_match_device (hns_roce_acpi_match , dev );
3929+ if (!acpi_id ) {
3930+ dev_err (dev , "device is not compatible!\n" );
3931+ return - ENXIO ;
3932+ }
3933+ hr_dev -> hw = (const struct hns_roce_hw * ) acpi_id -> driver_data ;
3934+ if (!hr_dev -> hw ) {
3935+ dev_err (dev , "couldn't get H/W specific ACPI data!\n" );
3936+ return - ENXIO ;
3937+ }
3938+ } else {
3939+ dev_err (dev , "can't read compatibility data from DT or ACPI\n" );
3940+ return - ENXIO ;
3941+ }
3942+
3943+ /* get the mapped register base address */
3944+ res = platform_get_resource (hr_dev -> pdev , IORESOURCE_MEM , 0 );
3945+ if (!res ) {
3946+ dev_err (dev , "memory resource not found!\n" );
3947+ return - EINVAL ;
3948+ }
3949+ hr_dev -> reg_base = devm_ioremap_resource (dev , res );
3950+ if (IS_ERR (hr_dev -> reg_base ))
3951+ return PTR_ERR (hr_dev -> reg_base );
3952+
3953+ /* read the node_guid of IB device from the DT or ACPI */
3954+ ret = device_property_read_u8_array (dev , "node-guid" ,
3955+ (u8 * )& hr_dev -> ib_dev .node_guid ,
3956+ GUID_LEN );
3957+ if (ret ) {
3958+ dev_err (dev , "couldn't get node_guid from DT or ACPI!\n" );
3959+ return ret ;
3960+ }
3961+
3962+ /* get the RoCE associated ethernet ports or netdevices */
3963+ for (i = 0 ; i < HNS_ROCE_MAX_PORTS ; i ++ ) {
3964+ if (dev_of_node (dev )) {
3965+ net_node = of_parse_phandle (dev -> of_node , "eth-handle" ,
3966+ i );
3967+ if (!net_node )
3968+ continue ;
3969+ pdev = of_find_device_by_node (net_node );
3970+ } else if (is_acpi_device_node (dev -> fwnode )) {
3971+ struct acpi_reference_args args ;
3972+ struct fwnode_handle * fwnode ;
3973+
3974+ ret = acpi_node_get_property_reference (dev -> fwnode ,
3975+ "eth-handle" ,
3976+ i , & args );
3977+ if (ret )
3978+ continue ;
3979+ fwnode = acpi_fwnode_handle (args .adev );
3980+ pdev = hns_roce_find_pdev (fwnode );
3981+ } else {
3982+ dev_err (dev , "cannot read data from DT or ACPI\n" );
3983+ return - ENXIO ;
3984+ }
3985+
3986+ if (pdev ) {
3987+ netdev = platform_get_drvdata (pdev );
3988+ phy_port = (u8 )i ;
3989+ if (netdev ) {
3990+ hr_dev -> iboe .netdevs [port_cnt ] = netdev ;
3991+ hr_dev -> iboe .phy_port [port_cnt ] = phy_port ;
3992+ } else {
3993+ dev_err (dev , "no netdev found with pdev %s\n" ,
3994+ pdev -> name );
3995+ return - ENODEV ;
3996+ }
3997+ port_cnt ++ ;
3998+ }
3999+ }
4000+
4001+ if (port_cnt == 0 ) {
4002+ dev_err (dev , "unable to get eth-handle for available ports!\n" );
4003+ return - EINVAL ;
4004+ }
4005+
4006+ hr_dev -> caps .num_ports = port_cnt ;
4007+
4008+ /* cmd issue mode: 0 is poll, 1 is event */
4009+ hr_dev -> cmd_mod = 1 ;
4010+ hr_dev -> loop_idc = 0 ;
4011+
4012+ /* read the interrupt names from the DT or ACPI */
4013+ ret = device_property_read_string_array (dev , "interrupt-names" ,
4014+ hr_dev -> irq_names ,
4015+ HNS_ROCE_MAX_IRQ_NUM );
4016+ if (ret < 0 ) {
4017+ dev_err (dev , "couldn't get interrupt names from DT or ACPI!\n" );
4018+ return ret ;
4019+ }
4020+
4021+ /* fetch the interrupt numbers */
4022+ for (i = 0 ; i < HNS_ROCE_MAX_IRQ_NUM ; i ++ ) {
4023+ hr_dev -> irq [i ] = platform_get_irq (hr_dev -> pdev , i );
4024+ if (hr_dev -> irq [i ] <= 0 ) {
4025+ dev_err (dev , "platform get of irq[=%d] failed!\n" , i );
4026+ return - EINVAL ;
4027+ }
4028+ }
4029+
4030+ return 0 ;
4031+ }
4032+
4033+ /**
4034+ * hns_roce_probe - RoCE driver entrance
4035+ * @pdev: pointer to platform device
4036+ * Return : int
4037+ *
4038+ */
4039+ static int hns_roce_probe (struct platform_device * pdev )
4040+ {
4041+ int ret ;
4042+ struct hns_roce_dev * hr_dev ;
4043+ struct device * dev = & pdev -> dev ;
4044+
4045+ hr_dev = (struct hns_roce_dev * )ib_alloc_device (sizeof (* hr_dev ));
4046+ if (!hr_dev )
4047+ return - ENOMEM ;
4048+
4049+ hr_dev -> pdev = pdev ;
4050+ platform_set_drvdata (pdev , hr_dev );
4051+
4052+ if (dma_set_mask_and_coherent (dev , DMA_BIT_MASK (64ULL )) &&
4053+ dma_set_mask_and_coherent (dev , DMA_BIT_MASK (32ULL ))) {
4054+ dev_err (dev , "Not usable DMA addressing mode\n" );
4055+ ret = - EIO ;
4056+ goto error_failed_get_cfg ;
4057+ }
4058+
4059+ ret = hns_roce_get_cfg (hr_dev );
4060+ if (ret ) {
4061+ dev_err (dev , "Get Configuration failed!\n" );
4062+ goto error_failed_get_cfg ;
4063+ }
4064+
4065+ ret = hns_roce_init (hr_dev );
4066+ if (ret ) {
4067+ dev_err (dev , "RoCE engine init failed!\n" );
4068+ goto error_failed_get_cfg ;
4069+ }
4070+
4071+ return 0 ;
4072+
4073+ error_failed_get_cfg :
4074+ ib_dealloc_device (& hr_dev -> ib_dev );
4075+
4076+ return ret ;
4077+ }
4078+
4079+ /**
4080+ * hns_roce_remove - remove RoCE device
4081+ * @pdev: pointer to platform device
4082+ */
4083+ static int hns_roce_remove (struct platform_device * pdev )
4084+ {
4085+ struct hns_roce_dev * hr_dev = platform_get_drvdata (pdev );
4086+
4087+ hns_roce_exit (hr_dev );
4088+ ib_dealloc_device (& hr_dev -> ib_dev );
4089+
4090+ return 0 ;
4091+ }
4092+
4093+ static struct platform_driver hns_roce_driver = {
4094+ .probe = hns_roce_probe ,
4095+ .remove = hns_roce_remove ,
4096+ .driver = {
4097+ .name = DRV_NAME ,
4098+ .of_match_table = hns_roce_of_match ,
4099+ .acpi_match_table = ACPI_PTR (hns_roce_acpi_match ),
4100+ },
4101+ };
4102+
4103+ module_platform_driver (hns_roce_driver );
4104+
4105+ MODULE_LICENSE ("Dual BSD/GPL" );
4106+ MODULE_AUTHOR (
"Wei Hu <[email protected] >" );
4107+ MODULE_AUTHOR (
"Nenglong Zhao <[email protected] >" );
4108+ MODULE_AUTHOR (
"Lijun Ou <[email protected] >" );
4109+ MODULE_DESCRIPTION ("Hisilicon Hip06 Family RoCE Driver" );
0 commit comments