linux/drivers/net/ethernet/emulex/benet/be_roce.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2005 - 2013 Emulex
   3 * All rights reserved.
   4 *
   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.
   9 *
  10 * Contact Information:
  11 * linux-drivers@emulex.com
  12 *
  13 * Emulex
  14 * 3333 Susan Street
  15 * Costa Mesa, CA 92626
  16 */
  17
  18#include <linux/mutex.h>
  19#include <linux/list.h>
  20#include <linux/netdevice.h>
  21#include <linux/module.h>
  22
  23#include "be.h"
  24#include "be_cmds.h"
  25
  26static struct ocrdma_driver *ocrdma_drv;
  27static LIST_HEAD(be_adapter_list);
  28static DEFINE_MUTEX(be_adapter_list_lock);
  29
  30static void _be_roce_dev_add(struct be_adapter *adapter)
  31{
  32        struct be_dev_info dev_info;
  33        int i, num_vec;
  34        struct pci_dev *pdev = adapter->pdev;
  35
  36        if (!ocrdma_drv)
  37                return;
  38        if (pdev->device == OC_DEVICE_ID5) {
  39                /* only msix is supported on these devices */
  40                if (!msix_enabled(adapter))
  41                        return;
  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);
  45        } else {
  46                dev_info.dpp_unmapped_addr = 0;
  47                dev_info.dpp_unmapped_len = 0;
  48        }
  49        dev_info.pdev = adapter->pdev;
  50        dev_info.db = adapter->db;
  51        dev_info.unmapped_db = adapter->roce_db.io_addr;
  52        dev_info.db_page_size = adapter->roce_db.size;
  53        dev_info.db_total_size = adapter->roce_db.total_size;
  54        dev_info.netdev = adapter->netdev;
  55        memcpy(dev_info.mac_addr, adapter->netdev->dev_addr, ETH_ALEN);
  56        dev_info.dev_family = adapter->sli_family;
  57        if (msix_enabled(adapter)) {
  58                /* provide all the vectors, so that EQ creation response
  59                 * can decide which one to use.
  60                 */
  61                num_vec = adapter->num_msix_vec + adapter->num_msix_roce_vec;
  62                dev_info.intr_mode = BE_INTERRUPT_MODE_MSIX;
  63                dev_info.msix.num_vectors = min(num_vec, MAX_MSIX_VECTORS);
  64                /* provide start index of the vector,
  65                 * so in case of linear usage,
  66                 * it can use the base as starting point.
  67                 */
  68                dev_info.msix.start_vector = adapter->num_evt_qs;
  69                for (i = 0; i < dev_info.msix.num_vectors; i++) {
  70                        dev_info.msix.vector_list[i] =
  71                            adapter->msix_entries[i].vector;
  72                }
  73        } else {
  74                dev_info.msix.num_vectors = 0;
  75                dev_info.intr_mode = BE_INTERRUPT_MODE_INTX;
  76        }
  77        adapter->ocrdma_dev = ocrdma_drv->add(&dev_info);
  78}
  79
  80void be_roce_dev_add(struct be_adapter *adapter)
  81{
  82        if (be_roce_supported(adapter)) {
  83                INIT_LIST_HEAD(&adapter->entry);
  84                mutex_lock(&be_adapter_list_lock);
  85                list_add_tail(&adapter->entry, &be_adapter_list);
  86
  87                /* invoke add() routine of roce driver only if
  88                 * valid driver registered with add method and add() is not yet
  89                 * invoked on a given adapter.
  90                 */
  91                _be_roce_dev_add(adapter);
  92                mutex_unlock(&be_adapter_list_lock);
  93        }
  94}
  95
  96static void _be_roce_dev_remove(struct be_adapter *adapter)
  97{
  98        if (ocrdma_drv && ocrdma_drv->remove && adapter->ocrdma_dev)
  99                ocrdma_drv->remove(adapter->ocrdma_dev);
 100        adapter->ocrdma_dev = NULL;
 101}
 102
 103void be_roce_dev_remove(struct be_adapter *adapter)
 104{
 105        if (be_roce_supported(adapter)) {
 106                mutex_lock(&be_adapter_list_lock);
 107                _be_roce_dev_remove(adapter);
 108                list_del(&adapter->entry);
 109                mutex_unlock(&be_adapter_list_lock);
 110        }
 111}
 112
 113static void _be_roce_dev_open(struct be_adapter *adapter)
 114{
 115        if (ocrdma_drv && adapter->ocrdma_dev &&
 116            ocrdma_drv->state_change_handler)
 117                ocrdma_drv->state_change_handler(adapter->ocrdma_dev, 0);
 118}
 119
 120void be_roce_dev_open(struct be_adapter *adapter)
 121{
 122        if (be_roce_supported(adapter)) {
 123                mutex_lock(&be_adapter_list_lock);
 124                _be_roce_dev_open(adapter);
 125                mutex_unlock(&be_adapter_list_lock);
 126        }
 127}
 128
 129static void _be_roce_dev_close(struct be_adapter *adapter)
 130{
 131        if (ocrdma_drv && adapter->ocrdma_dev &&
 132            ocrdma_drv->state_change_handler)
 133                ocrdma_drv->state_change_handler(adapter->ocrdma_dev, 1);
 134}
 135
 136void be_roce_dev_close(struct be_adapter *adapter)
 137{
 138        if (be_roce_supported(adapter)) {
 139                mutex_lock(&be_adapter_list_lock);
 140                _be_roce_dev_close(adapter);
 141                mutex_unlock(&be_adapter_list_lock);
 142        }
 143}
 144
 145int be_roce_register_driver(struct ocrdma_driver *drv)
 146{
 147        struct be_adapter *dev;
 148
 149        mutex_lock(&be_adapter_list_lock);
 150        if (ocrdma_drv) {
 151                mutex_unlock(&be_adapter_list_lock);
 152                return -EINVAL;
 153        }
 154        ocrdma_drv = drv;
 155        list_for_each_entry(dev, &be_adapter_list, entry) {
 156                struct net_device *netdev;
 157                _be_roce_dev_add(dev);
 158                netdev = dev->netdev;
 159                if (netif_running(netdev) && netif_oper_up(netdev))
 160                        _be_roce_dev_open(dev);
 161        }
 162        mutex_unlock(&be_adapter_list_lock);
 163        return 0;
 164}
 165EXPORT_SYMBOL(be_roce_register_driver);
 166
 167void be_roce_unregister_driver(struct ocrdma_driver *drv)
 168{
 169        struct be_adapter *dev;
 170
 171        mutex_lock(&be_adapter_list_lock);
 172        list_for_each_entry(dev, &be_adapter_list, entry) {
 173                if (dev->ocrdma_dev)
 174                        _be_roce_dev_remove(dev);
 175        }
 176        ocrdma_drv = NULL;
 177        mutex_unlock(&be_adapter_list_lock);
 178}
 179EXPORT_SYMBOL(be_roce_unregister_driver);
 180