18498a30eSMustafa Ismail // SPDX-License-Identifier: GPL-2.0 or Linux-OpenIB 28498a30eSMustafa Ismail /* Copyright (c) 2015 - 2021 Intel Corporation */ 38498a30eSMustafa Ismail #include "main.h" 48498a30eSMustafa Ismail #include "i40iw_hw.h" 58498a30eSMustafa Ismail #include <linux/net/intel/i40e_client.h> 68498a30eSMustafa Ismail 78498a30eSMustafa Ismail static struct i40e_client i40iw_client; 88498a30eSMustafa Ismail 98498a30eSMustafa Ismail /** 108498a30eSMustafa Ismail * i40iw_l2param_change - handle mss change 118498a30eSMustafa Ismail * @cdev_info: parent lan device information structure with data/ops 128498a30eSMustafa Ismail * @client: client for parameter change 138498a30eSMustafa Ismail * @params: new parameters from L2 148498a30eSMustafa Ismail */ 158498a30eSMustafa Ismail static void i40iw_l2param_change(struct i40e_info *cdev_info, 168498a30eSMustafa Ismail struct i40e_client *client, 178498a30eSMustafa Ismail struct i40e_params *params) 188498a30eSMustafa Ismail { 198498a30eSMustafa Ismail struct irdma_l2params l2params = {}; 208498a30eSMustafa Ismail struct irdma_device *iwdev; 218498a30eSMustafa Ismail struct ib_device *ibdev; 228498a30eSMustafa Ismail 238498a30eSMustafa Ismail ibdev = ib_device_get_by_netdev(cdev_info->netdev, RDMA_DRIVER_IRDMA); 248498a30eSMustafa Ismail if (!ibdev) 258498a30eSMustafa Ismail return; 268498a30eSMustafa Ismail 278498a30eSMustafa Ismail iwdev = to_iwdev(ibdev); 288498a30eSMustafa Ismail 298498a30eSMustafa Ismail if (iwdev->vsi.mtu != params->mtu) { 308498a30eSMustafa Ismail l2params.mtu_changed = true; 318498a30eSMustafa Ismail l2params.mtu = params->mtu; 328498a30eSMustafa Ismail } 338498a30eSMustafa Ismail irdma_change_l2params(&iwdev->vsi, &l2params); 348498a30eSMustafa Ismail ib_device_put(ibdev); 358498a30eSMustafa Ismail } 368498a30eSMustafa Ismail 378498a30eSMustafa Ismail /** 388498a30eSMustafa Ismail * i40iw_close - client interface operation close for iwarp/uda device 398498a30eSMustafa Ismail * @cdev_info: parent lan device information structure with data/ops 408498a30eSMustafa Ismail * @client: client to close 418498a30eSMustafa Ismail * @reset: flag to indicate close on reset 428498a30eSMustafa Ismail * 438498a30eSMustafa Ismail * Called by the lan driver during the processing of client unregister 448498a30eSMustafa Ismail * Destroy and clean up the driver resources 458498a30eSMustafa Ismail */ 468498a30eSMustafa Ismail static void i40iw_close(struct i40e_info *cdev_info, struct i40e_client *client, 478498a30eSMustafa Ismail bool reset) 488498a30eSMustafa Ismail { 498498a30eSMustafa Ismail struct irdma_device *iwdev; 508498a30eSMustafa Ismail struct ib_device *ibdev; 518498a30eSMustafa Ismail 528498a30eSMustafa Ismail ibdev = ib_device_get_by_netdev(cdev_info->netdev, RDMA_DRIVER_IRDMA); 538498a30eSMustafa Ismail if (WARN_ON(!ibdev)) 548498a30eSMustafa Ismail return; 558498a30eSMustafa Ismail 568498a30eSMustafa Ismail iwdev = to_iwdev(ibdev); 578498a30eSMustafa Ismail if (reset) 585b1e985fSSindhu Devale iwdev->rf->reset = true; 598498a30eSMustafa Ismail 608498a30eSMustafa Ismail iwdev->iw_status = 0; 618498a30eSMustafa Ismail irdma_port_ibevent(iwdev); 628498a30eSMustafa Ismail ib_unregister_device_and_put(ibdev); 638498a30eSMustafa Ismail pr_debug("INIT: Gen1 PF[%d] close complete\n", PCI_FUNC(cdev_info->pcidev->devfn)); 648498a30eSMustafa Ismail } 658498a30eSMustafa Ismail 668498a30eSMustafa Ismail static void i40iw_request_reset(struct irdma_pci_f *rf) 678498a30eSMustafa Ismail { 688498a30eSMustafa Ismail struct i40e_info *cdev_info = rf->cdev; 698498a30eSMustafa Ismail 708498a30eSMustafa Ismail cdev_info->ops->request_reset(cdev_info, &i40iw_client, 1); 718498a30eSMustafa Ismail } 728498a30eSMustafa Ismail 738498a30eSMustafa Ismail static void i40iw_fill_device_info(struct irdma_device *iwdev, struct i40e_info *cdev_info) 748498a30eSMustafa Ismail { 758498a30eSMustafa Ismail struct irdma_pci_f *rf = iwdev->rf; 768498a30eSMustafa Ismail 778498a30eSMustafa Ismail rf->rdma_ver = IRDMA_GEN_1; 788498a30eSMustafa Ismail rf->gen_ops.request_reset = i40iw_request_reset; 798498a30eSMustafa Ismail rf->pcidev = cdev_info->pcidev; 80b2001896SMustafa Ismail rf->pf_id = cdev_info->fid; 818498a30eSMustafa Ismail rf->hw.hw_addr = cdev_info->hw_addr; 828498a30eSMustafa Ismail rf->cdev = cdev_info; 838498a30eSMustafa Ismail rf->msix_count = cdev_info->msix_count; 848498a30eSMustafa Ismail rf->msix_entries = cdev_info->msix_entries; 858498a30eSMustafa Ismail rf->limits_sel = 5; 868498a30eSMustafa Ismail rf->protocol_used = IRDMA_IWARP_PROTOCOL_ONLY; 878498a30eSMustafa Ismail rf->iwdev = iwdev; 888498a30eSMustafa Ismail 898498a30eSMustafa Ismail iwdev->init_state = INITIAL_STATE; 908498a30eSMustafa Ismail iwdev->rcv_wnd = IRDMA_CM_DEFAULT_RCV_WND_SCALED; 918498a30eSMustafa Ismail iwdev->rcv_wscale = IRDMA_CM_DEFAULT_RCV_WND_SCALE; 928498a30eSMustafa Ismail iwdev->netdev = cdev_info->netdev; 938498a30eSMustafa Ismail iwdev->vsi_num = 0; 948498a30eSMustafa Ismail } 958498a30eSMustafa Ismail 968498a30eSMustafa Ismail /** 978498a30eSMustafa Ismail * i40iw_open - client interface operation open for iwarp/uda device 988498a30eSMustafa Ismail * @cdev_info: parent lan device information structure with data/ops 998498a30eSMustafa Ismail * @client: iwarp client information, provided during registration 1008498a30eSMustafa Ismail * 1018498a30eSMustafa Ismail * Called by the lan driver during the processing of client register 1028498a30eSMustafa Ismail * Create device resources, set up queues, pble and hmc objects and 1038498a30eSMustafa Ismail * register the device with the ib verbs interface 1048498a30eSMustafa Ismail * Return 0 if successful, otherwise return error 1058498a30eSMustafa Ismail */ 1068498a30eSMustafa Ismail static int i40iw_open(struct i40e_info *cdev_info, struct i40e_client *client) 1078498a30eSMustafa Ismail { 1088498a30eSMustafa Ismail struct irdma_l2params l2params = {}; 1098498a30eSMustafa Ismail struct irdma_device *iwdev; 1108498a30eSMustafa Ismail struct irdma_pci_f *rf; 1118498a30eSMustafa Ismail int err = -EIO; 1128498a30eSMustafa Ismail int i; 1138498a30eSMustafa Ismail u16 qset; 1148498a30eSMustafa Ismail u16 last_qset = IRDMA_NO_QSET; 1158498a30eSMustafa Ismail 1168498a30eSMustafa Ismail iwdev = ib_alloc_device(irdma_device, ibdev); 1178498a30eSMustafa Ismail if (!iwdev) 1188498a30eSMustafa Ismail return -ENOMEM; 1198498a30eSMustafa Ismail 1208498a30eSMustafa Ismail iwdev->rf = kzalloc(sizeof(*rf), GFP_KERNEL); 1218498a30eSMustafa Ismail if (!iwdev->rf) { 1228498a30eSMustafa Ismail ib_dealloc_device(&iwdev->ibdev); 1238498a30eSMustafa Ismail return -ENOMEM; 1248498a30eSMustafa Ismail } 1258498a30eSMustafa Ismail 1268498a30eSMustafa Ismail i40iw_fill_device_info(iwdev, cdev_info); 1278498a30eSMustafa Ismail rf = iwdev->rf; 1288498a30eSMustafa Ismail 1298498a30eSMustafa Ismail if (irdma_ctrl_init_hw(rf)) { 1308498a30eSMustafa Ismail err = -EIO; 1318498a30eSMustafa Ismail goto err_ctrl_init; 1328498a30eSMustafa Ismail } 1338498a30eSMustafa Ismail 1348498a30eSMustafa Ismail l2params.mtu = (cdev_info->params.mtu) ? cdev_info->params.mtu : IRDMA_DEFAULT_MTU; 1358498a30eSMustafa Ismail for (i = 0; i < I40E_CLIENT_MAX_USER_PRIORITY; i++) { 1368498a30eSMustafa Ismail qset = cdev_info->params.qos.prio_qos[i].qs_handle; 1378498a30eSMustafa Ismail l2params.up2tc[i] = cdev_info->params.qos.prio_qos[i].tc; 1388498a30eSMustafa Ismail l2params.qs_handle_list[i] = qset; 1398498a30eSMustafa Ismail if (last_qset == IRDMA_NO_QSET) 1408498a30eSMustafa Ismail last_qset = qset; 1418498a30eSMustafa Ismail else if ((qset != last_qset) && (qset != IRDMA_NO_QSET)) 14283483055SMustafa Ismail iwdev->dcb_vlan_mode = true; 1438498a30eSMustafa Ismail } 1448498a30eSMustafa Ismail 1458498a30eSMustafa Ismail if (irdma_rt_init_hw(iwdev, &l2params)) { 1468498a30eSMustafa Ismail err = -EIO; 1478498a30eSMustafa Ismail goto err_rt_init; 1488498a30eSMustafa Ismail } 1498498a30eSMustafa Ismail 1508498a30eSMustafa Ismail err = irdma_ib_register_device(iwdev); 1518498a30eSMustafa Ismail if (err) 1528498a30eSMustafa Ismail goto err_ibreg; 1538498a30eSMustafa Ismail 1548498a30eSMustafa Ismail ibdev_dbg(&iwdev->ibdev, "INIT: Gen1 PF[%d] open success\n", 1558498a30eSMustafa Ismail PCI_FUNC(rf->pcidev->devfn)); 1568498a30eSMustafa Ismail 1578498a30eSMustafa Ismail return 0; 1588498a30eSMustafa Ismail 1598498a30eSMustafa Ismail err_ibreg: 1608498a30eSMustafa Ismail irdma_rt_deinit_hw(iwdev); 1618498a30eSMustafa Ismail err_rt_init: 1628498a30eSMustafa Ismail irdma_ctrl_deinit_hw(rf); 1638498a30eSMustafa Ismail err_ctrl_init: 1648498a30eSMustafa Ismail kfree(iwdev->rf); 1658498a30eSMustafa Ismail ib_dealloc_device(&iwdev->ibdev); 1668498a30eSMustafa Ismail 1678498a30eSMustafa Ismail return err; 1688498a30eSMustafa Ismail } 1698498a30eSMustafa Ismail 1708498a30eSMustafa Ismail /* client interface functions */ 1718498a30eSMustafa Ismail static const struct i40e_client_ops i40e_ops = { 1728498a30eSMustafa Ismail .open = i40iw_open, 1738498a30eSMustafa Ismail .close = i40iw_close, 1748498a30eSMustafa Ismail .l2_param_change = i40iw_l2param_change 1758498a30eSMustafa Ismail }; 1768498a30eSMustafa Ismail 1778498a30eSMustafa Ismail static struct i40e_client i40iw_client = { 1788498a30eSMustafa Ismail .ops = &i40e_ops, 1798498a30eSMustafa Ismail .type = I40E_CLIENT_IWARP, 1808498a30eSMustafa Ismail }; 1818498a30eSMustafa Ismail 1828498a30eSMustafa Ismail static int i40iw_probe(struct auxiliary_device *aux_dev, const struct auxiliary_device_id *id) 1838498a30eSMustafa Ismail { 1848498a30eSMustafa Ismail struct i40e_auxiliary_device *i40e_adev = container_of(aux_dev, 1858498a30eSMustafa Ismail struct i40e_auxiliary_device, 1868498a30eSMustafa Ismail aux_dev); 1878498a30eSMustafa Ismail struct i40e_info *cdev_info = i40e_adev->ldev; 1888498a30eSMustafa Ismail 1898498a30eSMustafa Ismail strncpy(i40iw_client.name, "irdma", I40E_CLIENT_STR_LENGTH); 1908498a30eSMustafa Ismail i40e_client_device_register(cdev_info, &i40iw_client); 1918498a30eSMustafa Ismail 1928498a30eSMustafa Ismail return 0; 1938498a30eSMustafa Ismail } 1948498a30eSMustafa Ismail 1958498a30eSMustafa Ismail static void i40iw_remove(struct auxiliary_device *aux_dev) 1968498a30eSMustafa Ismail { 1978498a30eSMustafa Ismail struct i40e_auxiliary_device *i40e_adev = container_of(aux_dev, 1988498a30eSMustafa Ismail struct i40e_auxiliary_device, 1998498a30eSMustafa Ismail aux_dev); 2008498a30eSMustafa Ismail struct i40e_info *cdev_info = i40e_adev->ldev; 2018498a30eSMustafa Ismail 202c40238e3SZhu Yanjun i40e_client_device_unregister(cdev_info); 2038498a30eSMustafa Ismail } 2048498a30eSMustafa Ismail 2058498a30eSMustafa Ismail static const struct auxiliary_device_id i40iw_auxiliary_id_table[] = { 2068498a30eSMustafa Ismail {.name = "i40e.iwarp", }, 2078498a30eSMustafa Ismail {}, 2088498a30eSMustafa Ismail }; 2098498a30eSMustafa Ismail 2108498a30eSMustafa Ismail MODULE_DEVICE_TABLE(auxiliary, i40iw_auxiliary_id_table); 2118498a30eSMustafa Ismail 2128498a30eSMustafa Ismail struct auxiliary_driver i40iw_auxiliary_drv = { 2138498a30eSMustafa Ismail .name = "gen_1", 2148498a30eSMustafa Ismail .id_table = i40iw_auxiliary_id_table, 2158498a30eSMustafa Ismail .probe = i40iw_probe, 2168498a30eSMustafa Ismail .remove = i40iw_remove, 2178498a30eSMustafa Ismail }; 218