brintos

brintos / linux-shallow public Read only

0
0
Text · 4.1 KiB · 521c4c2 Raw
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