linux/drivers/net/wireless/ralink/rt2x00/rt2x00pci.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3        Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
   4        <http://rt2x00.serialmonkey.com>
   5
   6 */
   7
   8/*
   9        Module: rt2x00pci
  10        Abstract: rt2x00 generic pci device routines.
  11 */
  12
  13#include <linux/dma-mapping.h>
  14#include <linux/kernel.h>
  15#include <linux/module.h>
  16#include <linux/pci.h>
  17#include <linux/slab.h>
  18
  19#include "rt2x00.h"
  20#include "rt2x00pci.h"
  21
  22/*
  23 * PCI driver handlers.
  24 */
  25static void rt2x00pci_free_reg(struct rt2x00_dev *rt2x00dev)
  26{
  27        kfree(rt2x00dev->rf);
  28        rt2x00dev->rf = NULL;
  29
  30        kfree(rt2x00dev->eeprom);
  31        rt2x00dev->eeprom = NULL;
  32
  33        if (rt2x00dev->csr.base) {
  34                iounmap(rt2x00dev->csr.base);
  35                rt2x00dev->csr.base = NULL;
  36        }
  37}
  38
  39static int rt2x00pci_alloc_reg(struct rt2x00_dev *rt2x00dev)
  40{
  41        struct pci_dev *pci_dev = to_pci_dev(rt2x00dev->dev);
  42
  43        rt2x00dev->csr.base = pci_ioremap_bar(pci_dev, 0);
  44        if (!rt2x00dev->csr.base)
  45                goto exit;
  46
  47        rt2x00dev->eeprom = kzalloc(rt2x00dev->ops->eeprom_size, GFP_KERNEL);
  48        if (!rt2x00dev->eeprom)
  49                goto exit;
  50
  51        rt2x00dev->rf = kzalloc(rt2x00dev->ops->rf_size, GFP_KERNEL);
  52        if (!rt2x00dev->rf)
  53                goto exit;
  54
  55        return 0;
  56
  57exit:
  58        rt2x00_probe_err("Failed to allocate registers\n");
  59
  60        rt2x00pci_free_reg(rt2x00dev);
  61
  62        return -ENOMEM;
  63}
  64
  65int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops)
  66{
  67        struct ieee80211_hw *hw;
  68        struct rt2x00_dev *rt2x00dev;
  69        int retval;
  70        u16 chip;
  71
  72        retval = pci_enable_device(pci_dev);
  73        if (retval) {
  74                rt2x00_probe_err("Enable device failed\n");
  75                return retval;
  76        }
  77
  78        retval = pci_request_regions(pci_dev, pci_name(pci_dev));
  79        if (retval) {
  80                rt2x00_probe_err("PCI request regions failed\n");
  81                goto exit_disable_device;
  82        }
  83
  84        pci_set_master(pci_dev);
  85
  86        if (pci_set_mwi(pci_dev))
  87                rt2x00_probe_err("MWI not available\n");
  88
  89        if (dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(32))) {
  90                rt2x00_probe_err("PCI DMA not supported\n");
  91                retval = -EIO;
  92                goto exit_release_regions;
  93        }
  94
  95        hw = ieee80211_alloc_hw(sizeof(struct rt2x00_dev), ops->hw);
  96        if (!hw) {
  97                rt2x00_probe_err("Failed to allocate hardware\n");
  98                retval = -ENOMEM;
  99                goto exit_release_regions;
 100        }
 101
 102        pci_set_drvdata(pci_dev, hw);
 103
 104        rt2x00dev = hw->priv;
 105        rt2x00dev->dev = &pci_dev->dev;
 106        rt2x00dev->ops = ops;
 107        rt2x00dev->hw = hw;
 108        rt2x00dev->irq = pci_dev->irq;
 109        rt2x00dev->name = ops->name;
 110
 111        if (pci_is_pcie(pci_dev))
 112                rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCIE);
 113        else
 114                rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI);
 115
 116        retval = rt2x00pci_alloc_reg(rt2x00dev);
 117        if (retval)
 118                goto exit_free_device;
 119
 120        /*
 121         * Because rt3290 chip use different efuse offset to read efuse data.
 122         * So before read efuse it need to indicate it is the
 123         * rt3290 or not.
 124         */
 125        pci_read_config_word(pci_dev, PCI_DEVICE_ID, &chip);
 126        rt2x00dev->chip.rt = chip;
 127
 128        retval = rt2x00lib_probe_dev(rt2x00dev);
 129        if (retval)
 130                goto exit_free_reg;
 131
 132        return 0;
 133
 134exit_free_reg:
 135        rt2x00pci_free_reg(rt2x00dev);
 136
 137exit_free_device:
 138        ieee80211_free_hw(hw);
 139
 140exit_release_regions:
 141        pci_clear_mwi(pci_dev);
 142        pci_release_regions(pci_dev);
 143
 144exit_disable_device:
 145        pci_disable_device(pci_dev);
 146
 147        return retval;
 148}
 149EXPORT_SYMBOL_GPL(rt2x00pci_probe);
 150
 151void rt2x00pci_remove(struct pci_dev *pci_dev)
 152{
 153        struct ieee80211_hw *hw = pci_get_drvdata(pci_dev);
 154        struct rt2x00_dev *rt2x00dev = hw->priv;
 155
 156        /*
 157         * Free all allocated data.
 158         */
 159        rt2x00lib_remove_dev(rt2x00dev);
 160        rt2x00pci_free_reg(rt2x00dev);
 161        ieee80211_free_hw(hw);
 162
 163        /*
 164         * Free the PCI device data.
 165         */
 166        pci_clear_mwi(pci_dev);
 167        pci_disable_device(pci_dev);
 168        pci_release_regions(pci_dev);
 169}
 170EXPORT_SYMBOL_GPL(rt2x00pci_remove);
 171
 172static int __maybe_unused rt2x00pci_suspend(struct device *dev)
 173{
 174        struct ieee80211_hw *hw = dev_get_drvdata(dev);
 175        struct rt2x00_dev *rt2x00dev = hw->priv;
 176
 177        return rt2x00lib_suspend(rt2x00dev);
 178}
 179
 180static int __maybe_unused rt2x00pci_resume(struct device *dev)
 181{
 182        struct ieee80211_hw *hw = dev_get_drvdata(dev);
 183        struct rt2x00_dev *rt2x00dev = hw->priv;
 184
 185        return rt2x00lib_resume(rt2x00dev);
 186}
 187
 188SIMPLE_DEV_PM_OPS(rt2x00pci_pm_ops, rt2x00pci_suspend, rt2x00pci_resume);
 189EXPORT_SYMBOL_GPL(rt2x00pci_pm_ops);
 190
 191/*
 192 * rt2x00pci module information.
 193 */
 194MODULE_AUTHOR(DRV_PROJECT);
 195MODULE_VERSION(DRV_VERSION);
 196MODULE_DESCRIPTION("rt2x00 pci library");
 197MODULE_LICENSE("GPL");
 198