Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright (c) 2004 Topspin Communications.  All rights reserved.
0003  *
0004  * This software is available to you under a choice of one of two
0005  * licenses.  You may choose to be licensed under the terms of the GNU
0006  * General Public License (GPL) Version 2, available from the file
0007  * COPYING in the main directory of this source tree, or the
0008  * OpenIB.org BSD license below:
0009  *
0010  *     Redistribution and use in source and binary forms, with or
0011  *     without modification, are permitted provided that the following
0012  *     conditions are met:
0013  *
0014  *      - Redistributions of source code must retain the above
0015  *        copyright notice, this list of conditions and the following
0016  *        disclaimer.
0017  *
0018  *      - Redistributions in binary form must reproduce the above
0019  *        copyright notice, this list of conditions and the following
0020  *        disclaimer in the documentation and/or other materials
0021  *        provided with the distribution.
0022  *
0023  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
0024  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
0025  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
0026  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
0027  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
0028  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
0029  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
0030  * SOFTWARE.
0031  */
0032 
0033 #include <linux/errno.h>
0034 #include <linux/pci.h>
0035 #include <linux/delay.h>
0036 #include <linux/slab.h>
0037 
0038 #include "mthca_dev.h"
0039 #include "mthca_cmd.h"
0040 
0041 int mthca_reset(struct mthca_dev *mdev)
0042 {
0043     int i;
0044     int err = 0;
0045     u32 *hca_header    = NULL;
0046     u32 *bridge_header = NULL;
0047     struct pci_dev *bridge = NULL;
0048     int bridge_pcix_cap = 0;
0049     int hca_pcie_cap = 0;
0050     int hca_pcix_cap = 0;
0051 
0052     u16 devctl;
0053     u16 linkctl;
0054 
0055 #define MTHCA_RESET_OFFSET 0xf0010
0056 #define MTHCA_RESET_VALUE  swab32(1)
0057 
0058     /*
0059      * Reset the chip.  This is somewhat ugly because we have to
0060      * save off the PCI header before reset and then restore it
0061      * after the chip reboots.  We skip config space offsets 22
0062      * and 23 since those have a special meaning.
0063      *
0064      * To make matters worse, for Tavor (PCI-X HCA) we have to
0065      * find the associated bridge device and save off its PCI
0066      * header as well.
0067      */
0068 
0069     if (!(mdev->mthca_flags & MTHCA_FLAG_PCIE)) {
0070         /* Look for the bridge -- its device ID will be 2 more
0071            than HCA's device ID. */
0072         while ((bridge = pci_get_device(mdev->pdev->vendor,
0073                         mdev->pdev->device + 2,
0074                         bridge)) != NULL) {
0075             if (bridge->hdr_type    == PCI_HEADER_TYPE_BRIDGE &&
0076                 bridge->subordinate == mdev->pdev->bus) {
0077                 mthca_dbg(mdev, "Found bridge: %s\n",
0078                       pci_name(bridge));
0079                 break;
0080             }
0081         }
0082 
0083         if (!bridge) {
0084             /*
0085              * Didn't find a bridge for a Tavor device --
0086              * assume we're in no-bridge mode and hope for
0087              * the best.
0088              */
0089             mthca_warn(mdev, "No bridge found for %s\n",
0090                   pci_name(mdev->pdev));
0091         }
0092 
0093     }
0094 
0095     /* For Arbel do we need to save off the full 4K PCI Express header?? */
0096     hca_header = kmalloc(256, GFP_KERNEL);
0097     if (!hca_header) {
0098         err = -ENOMEM;
0099         goto put_dev;
0100     }
0101 
0102     for (i = 0; i < 64; ++i) {
0103         if (i == 22 || i == 23)
0104             continue;
0105         if (pci_read_config_dword(mdev->pdev, i * 4, hca_header + i)) {
0106             err = -ENODEV;
0107             mthca_err(mdev, "Couldn't save HCA "
0108                   "PCI header, aborting.\n");
0109             goto free_hca;
0110         }
0111     }
0112 
0113     hca_pcix_cap = pci_find_capability(mdev->pdev, PCI_CAP_ID_PCIX);
0114     hca_pcie_cap = pci_pcie_cap(mdev->pdev);
0115 
0116     if (bridge) {
0117         bridge_header = kmalloc(256, GFP_KERNEL);
0118         if (!bridge_header) {
0119             err = -ENOMEM;
0120             goto free_hca;
0121         }
0122 
0123         for (i = 0; i < 64; ++i) {
0124             if (i == 22 || i == 23)
0125                 continue;
0126             if (pci_read_config_dword(bridge, i * 4, bridge_header + i)) {
0127                 err = -ENODEV;
0128                 mthca_err(mdev, "Couldn't save HCA bridge "
0129                       "PCI header, aborting.\n");
0130                 goto free_bh;
0131             }
0132         }
0133         bridge_pcix_cap = pci_find_capability(bridge, PCI_CAP_ID_PCIX);
0134         if (!bridge_pcix_cap) {
0135                 err = -ENODEV;
0136                 mthca_err(mdev, "Couldn't locate HCA bridge "
0137                       "PCI-X capability, aborting.\n");
0138                 goto free_bh;
0139         }
0140     }
0141 
0142     /* actually hit reset */
0143     {
0144         void __iomem *reset = ioremap(pci_resource_start(mdev->pdev, 0) +
0145                           MTHCA_RESET_OFFSET, 4);
0146 
0147         if (!reset) {
0148             err = -ENOMEM;
0149             mthca_err(mdev, "Couldn't map HCA reset register, "
0150                   "aborting.\n");
0151             goto free_bh;
0152         }
0153 
0154         writel(MTHCA_RESET_VALUE, reset);
0155         iounmap(reset);
0156     }
0157 
0158     /* Docs say to wait one second before accessing device */
0159     msleep(1000);
0160 
0161     /* Now wait for PCI device to start responding again */
0162     {
0163         u32 v;
0164         int c = 0;
0165 
0166         for (c = 0; c < 100; ++c) {
0167             if (pci_read_config_dword(bridge ? bridge : mdev->pdev, 0, &v)) {
0168                 err = -ENODEV;
0169                 mthca_err(mdev, "Couldn't access HCA after reset, "
0170                       "aborting.\n");
0171                 goto free_bh;
0172             }
0173 
0174             if (v != 0xffffffff)
0175                 goto good;
0176 
0177             msleep(100);
0178         }
0179 
0180         err = -ENODEV;
0181         mthca_err(mdev, "PCI device did not come back after reset, "
0182               "aborting.\n");
0183         goto free_bh;
0184     }
0185 
0186 good:
0187     /* Now restore the PCI headers */
0188     if (bridge) {
0189         if (pci_write_config_dword(bridge, bridge_pcix_cap + 0x8,
0190                  bridge_header[(bridge_pcix_cap + 0x8) / 4])) {
0191             err = -ENODEV;
0192             mthca_err(mdev, "Couldn't restore HCA bridge Upstream "
0193                   "split transaction control, aborting.\n");
0194             goto free_bh;
0195         }
0196         if (pci_write_config_dword(bridge, bridge_pcix_cap + 0xc,
0197                  bridge_header[(bridge_pcix_cap + 0xc) / 4])) {
0198             err = -ENODEV;
0199             mthca_err(mdev, "Couldn't restore HCA bridge Downstream "
0200                   "split transaction control, aborting.\n");
0201             goto free_bh;
0202         }
0203         /*
0204          * Bridge control register is at 0x3e, so we'll
0205          * naturally restore it last in this loop.
0206          */
0207         for (i = 0; i < 16; ++i) {
0208             if (i * 4 == PCI_COMMAND)
0209                 continue;
0210 
0211             if (pci_write_config_dword(bridge, i * 4, bridge_header[i])) {
0212                 err = -ENODEV;
0213                 mthca_err(mdev, "Couldn't restore HCA bridge reg %x, "
0214                       "aborting.\n", i);
0215                 goto free_bh;
0216             }
0217         }
0218 
0219         if (pci_write_config_dword(bridge, PCI_COMMAND,
0220                        bridge_header[PCI_COMMAND / 4])) {
0221             err = -ENODEV;
0222             mthca_err(mdev, "Couldn't restore HCA bridge COMMAND, "
0223                   "aborting.\n");
0224             goto free_bh;
0225         }
0226     }
0227 
0228     if (hca_pcix_cap) {
0229         if (pci_write_config_dword(mdev->pdev, hca_pcix_cap,
0230                  hca_header[hca_pcix_cap / 4])) {
0231             err = -ENODEV;
0232             mthca_err(mdev, "Couldn't restore HCA PCI-X "
0233                   "command register, aborting.\n");
0234             goto free_bh;
0235         }
0236     }
0237 
0238     if (hca_pcie_cap) {
0239         devctl = hca_header[(hca_pcie_cap + PCI_EXP_DEVCTL) / 4];
0240         if (pcie_capability_write_word(mdev->pdev, PCI_EXP_DEVCTL,
0241                            devctl)) {
0242             err = -ENODEV;
0243             mthca_err(mdev, "Couldn't restore HCA PCI Express "
0244                   "Device Control register, aborting.\n");
0245             goto free_bh;
0246         }
0247         linkctl = hca_header[(hca_pcie_cap + PCI_EXP_LNKCTL) / 4];
0248         if (pcie_capability_write_word(mdev->pdev, PCI_EXP_LNKCTL,
0249                            linkctl)) {
0250             err = -ENODEV;
0251             mthca_err(mdev, "Couldn't restore HCA PCI Express "
0252                   "Link control register, aborting.\n");
0253             goto free_bh;
0254         }
0255     }
0256 
0257     for (i = 0; i < 16; ++i) {
0258         if (i * 4 == PCI_COMMAND)
0259             continue;
0260 
0261         if (pci_write_config_dword(mdev->pdev, i * 4, hca_header[i])) {
0262             err = -ENODEV;
0263             mthca_err(mdev, "Couldn't restore HCA reg %x, "
0264                   "aborting.\n", i);
0265             goto free_bh;
0266         }
0267     }
0268 
0269     if (pci_write_config_dword(mdev->pdev, PCI_COMMAND,
0270                    hca_header[PCI_COMMAND / 4])) {
0271         err = -ENODEV;
0272         mthca_err(mdev, "Couldn't restore HCA COMMAND, "
0273               "aborting.\n");
0274     }
0275 free_bh:
0276     kfree(bridge_header);
0277 free_hca:
0278     kfree(hca_header);
0279 put_dev:
0280     pci_dev_put(bridge);
0281     return err;
0282 }