158 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (C) 2005 - 2016 Broadcom4 * All rights reserved.5 *6 * Contact Information:7 * linux-drivers@emulex.com8 *9 * Emulex10 * 3333 Susan Street11 * Costa Mesa, CA 9262612 */13 14#include <linux/mutex.h>15#include <linux/list.h>16#include <linux/netdevice.h>17#include <linux/module.h>18 19#include "be.h"20#include "be_cmds.h"21 22static struct ocrdma_driver *ocrdma_drv;23static LIST_HEAD(be_adapter_list);24static DEFINE_MUTEX(be_adapter_list_lock);25 26static void _be_roce_dev_add(struct be_adapter *adapter)27{28 struct be_dev_info dev_info;29 int i, num_vec;30 struct pci_dev *pdev = adapter->pdev;31 32 if (!ocrdma_drv)33 return;34 35 if (ocrdma_drv->be_abi_version != BE_ROCE_ABI_VERSION) {36 dev_warn(&pdev->dev, "Cannot initialize RoCE due to ocrdma ABI mismatch\n");37 return;38 }39 40 if (pdev->device == OC_DEVICE_ID5) {41 /* only msix is supported on these devices */42 if (!msix_enabled(adapter))43 return;44 /* DPP region address and length */45 dev_info.dpp_unmapped_addr = pci_resource_start(pdev, 2);46 dev_info.dpp_unmapped_len = pci_resource_len(pdev, 2);47 } else {48 dev_info.dpp_unmapped_addr = 0;49 dev_info.dpp_unmapped_len = 0;50 }51 dev_info.pdev = adapter->pdev;52 dev_info.db = adapter->db;53 dev_info.unmapped_db = adapter->roce_db.io_addr;54 dev_info.db_page_size = adapter->roce_db.size;55 dev_info.db_total_size = adapter->roce_db.total_size;56 dev_info.netdev = adapter->netdev;57 memcpy(dev_info.mac_addr, adapter->netdev->dev_addr, ETH_ALEN);58 dev_info.dev_family = adapter->sli_family;59 if (msix_enabled(adapter)) {60 /* provide all the vectors, so that EQ creation response61 * can decide which one to use.62 */63 num_vec = adapter->num_msix_vec + adapter->num_msix_roce_vec;64 dev_info.intr_mode = BE_INTERRUPT_MODE_MSIX;65 dev_info.msix.num_vectors = min(num_vec, MAX_MSIX_VECTORS);66 /* provide start index of the vector,67 * so in case of linear usage,68 * it can use the base as starting point.69 */70 dev_info.msix.start_vector = adapter->num_evt_qs;71 for (i = 0; i < dev_info.msix.num_vectors; i++) {72 dev_info.msix.vector_list[i] =73 adapter->msix_entries[i].vector;74 }75 } else {76 dev_info.msix.num_vectors = 0;77 dev_info.intr_mode = BE_INTERRUPT_MODE_INTX;78 }79 adapter->ocrdma_dev = ocrdma_drv->add(&dev_info);80}81 82void be_roce_dev_add(struct be_adapter *adapter)83{84 if (be_roce_supported(adapter)) {85 INIT_LIST_HEAD(&adapter->entry);86 mutex_lock(&be_adapter_list_lock);87 list_add_tail(&adapter->entry, &be_adapter_list);88 89 /* invoke add() routine of roce driver only if90 * valid driver registered with add method and add() is not yet91 * invoked on a given adapter.92 */93 _be_roce_dev_add(adapter);94 mutex_unlock(&be_adapter_list_lock);95 }96}97 98static void _be_roce_dev_remove(struct be_adapter *adapter)99{100 if (ocrdma_drv && ocrdma_drv->remove && adapter->ocrdma_dev)101 ocrdma_drv->remove(adapter->ocrdma_dev);102 adapter->ocrdma_dev = NULL;103}104 105void be_roce_dev_remove(struct be_adapter *adapter)106{107 if (be_roce_supported(adapter)) {108 mutex_lock(&be_adapter_list_lock);109 _be_roce_dev_remove(adapter);110 list_del(&adapter->entry);111 mutex_unlock(&be_adapter_list_lock);112 }113}114 115void be_roce_dev_shutdown(struct be_adapter *adapter)116{117 if (be_roce_supported(adapter)) {118 mutex_lock(&be_adapter_list_lock);119 if (ocrdma_drv && adapter->ocrdma_dev &&120 ocrdma_drv->state_change_handler)121 ocrdma_drv->state_change_handler(adapter->ocrdma_dev,122 BE_DEV_SHUTDOWN);123 mutex_unlock(&be_adapter_list_lock);124 }125}126 127int be_roce_register_driver(struct ocrdma_driver *drv)128{129 struct be_adapter *dev;130 131 mutex_lock(&be_adapter_list_lock);132 if (ocrdma_drv) {133 mutex_unlock(&be_adapter_list_lock);134 return -EINVAL;135 }136 ocrdma_drv = drv;137 list_for_each_entry(dev, &be_adapter_list, entry) {138 _be_roce_dev_add(dev);139 }140 mutex_unlock(&be_adapter_list_lock);141 return 0;142}143EXPORT_SYMBOL(be_roce_register_driver);144 145void be_roce_unregister_driver(struct ocrdma_driver *drv)146{147 struct be_adapter *dev;148 149 mutex_lock(&be_adapter_list_lock);150 list_for_each_entry(dev, &be_adapter_list, entry) {151 if (dev->ocrdma_dev)152 _be_roce_dev_remove(dev);153 }154 ocrdma_drv = NULL;155 mutex_unlock(&be_adapter_list_lock);156}157EXPORT_SYMBOL(be_roce_unregister_driver);158