2 * Copyright (C) 2005 - 2011 Emulex
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License version 2
7 * as published by the Free Software Foundation. The full GNU General
8 * Public License is included in this distribution in the file called COPYING.
10 * Contact Information:
11 * linux-drivers@emulex.com
15 * Costa Mesa, CA 92626
18 #include <linux/mutex.h>
19 #include <linux/list.h>
20 #include <linux/netdevice.h>
21 #include <linux/module.h>
26 static struct ocrdma_driver *ocrdma_drv;
27 static LIST_HEAD(be_adapter_list);
28 static DEFINE_MUTEX(be_adapter_list_lock);
30 static void _be_roce_dev_add(struct be_adapter *adapter)
32 struct be_dev_info dev_info;
34 struct pci_dev *pdev = adapter->pdev;
38 if (pdev->device == OC_DEVICE_ID5) {
39 /* only msix is supported on these devices */
40 if (!msix_enabled(adapter))
42 /* DPP region address and length */
43 dev_info.dpp_unmapped_addr = pci_resource_start(pdev, 2);
44 dev_info.dpp_unmapped_len = pci_resource_len(pdev, 2);
46 dev_info.dpp_unmapped_addr = 0;
47 dev_info.dpp_unmapped_len = 0;
49 dev_info.pdev = adapter->pdev;
50 if (adapter->sli_family == SKYHAWK_SLI_FAMILY)
51 dev_info.db = adapter->db;
53 dev_info.db = adapter->roce_db.base;
54 dev_info.unmapped_db = adapter->roce_db.io_addr;
55 dev_info.db_page_size = adapter->roce_db.size;
56 dev_info.db_total_size = adapter->roce_db.total_size;
57 dev_info.netdev = adapter->netdev;
58 memcpy(dev_info.mac_addr, adapter->netdev->dev_addr, ETH_ALEN);
59 dev_info.dev_family = adapter->sli_family;
60 if (msix_enabled(adapter)) {
61 /* provide all the vectors, so that EQ creation response
62 * can decide which one to use.
64 num_vec = adapter->num_msix_vec + adapter->num_msix_roce_vec;
65 dev_info.intr_mode = BE_INTERRUPT_MODE_MSIX;
66 dev_info.msix.num_vectors = min(num_vec, MAX_ROCE_MSIX_VECTORS);
67 /* provide start index of the vector,
68 * so in case of linear usage,
69 * it can use the base as starting point.
71 dev_info.msix.start_vector = adapter->num_evt_qs;
72 for (i = 0; i < dev_info.msix.num_vectors; i++) {
73 dev_info.msix.vector_list[i] =
74 adapter->msix_entries[i].vector;
77 dev_info.msix.num_vectors = 0;
78 dev_info.intr_mode = BE_INTERRUPT_MODE_INTX;
80 adapter->ocrdma_dev = ocrdma_drv->add(&dev_info);
83 void be_roce_dev_add(struct be_adapter *adapter)
85 if (be_roce_supported(adapter)) {
86 INIT_LIST_HEAD(&adapter->entry);
87 mutex_lock(&be_adapter_list_lock);
88 list_add_tail(&adapter->entry, &be_adapter_list);
90 /* invoke add() routine of roce driver only if
91 * valid driver registered with add method and add() is not yet
92 * invoked on a given adapter.
94 _be_roce_dev_add(adapter);
95 mutex_unlock(&be_adapter_list_lock);
99 void _be_roce_dev_remove(struct be_adapter *adapter)
101 if (ocrdma_drv && ocrdma_drv->remove && adapter->ocrdma_dev)
102 ocrdma_drv->remove(adapter->ocrdma_dev);
103 adapter->ocrdma_dev = NULL;
106 void be_roce_dev_remove(struct be_adapter *adapter)
108 if (be_roce_supported(adapter)) {
109 mutex_lock(&be_adapter_list_lock);
110 _be_roce_dev_remove(adapter);
111 list_del(&adapter->entry);
112 mutex_unlock(&be_adapter_list_lock);
116 void _be_roce_dev_open(struct be_adapter *adapter)
118 if (ocrdma_drv && adapter->ocrdma_dev &&
119 ocrdma_drv->state_change_handler)
120 ocrdma_drv->state_change_handler(adapter->ocrdma_dev, 0);
123 void be_roce_dev_open(struct be_adapter *adapter)
125 if (be_roce_supported(adapter)) {
126 mutex_lock(&be_adapter_list_lock);
127 _be_roce_dev_open(adapter);
128 mutex_unlock(&be_adapter_list_lock);
132 void _be_roce_dev_close(struct be_adapter *adapter)
134 if (ocrdma_drv && adapter->ocrdma_dev &&
135 ocrdma_drv->state_change_handler)
136 ocrdma_drv->state_change_handler(adapter->ocrdma_dev, 1);
139 void be_roce_dev_close(struct be_adapter *adapter)
141 if (be_roce_supported(adapter)) {
142 mutex_lock(&be_adapter_list_lock);
143 _be_roce_dev_close(adapter);
144 mutex_unlock(&be_adapter_list_lock);
148 int be_roce_register_driver(struct ocrdma_driver *drv)
150 struct be_adapter *dev;
152 mutex_lock(&be_adapter_list_lock);
154 mutex_unlock(&be_adapter_list_lock);
158 list_for_each_entry(dev, &be_adapter_list, entry) {
159 struct net_device *netdev;
160 _be_roce_dev_add(dev);
161 netdev = dev->netdev;
162 if (netif_running(netdev) && netif_oper_up(netdev))
163 _be_roce_dev_open(dev);
165 mutex_unlock(&be_adapter_list_lock);
168 EXPORT_SYMBOL(be_roce_register_driver);
170 void be_roce_unregister_driver(struct ocrdma_driver *drv)
172 struct be_adapter *dev;
174 mutex_lock(&be_adapter_list_lock);
175 list_for_each_entry(dev, &be_adapter_list, entry) {
177 _be_roce_dev_remove(dev);
180 mutex_unlock(&be_adapter_list_lock);
182 EXPORT_SYMBOL(be_roce_unregister_driver);