Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003     Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
0004     <http://rt2x00.serialmonkey.com>
0005 
0006  */
0007 
0008 /*
0009     Module: rt2x00pci
0010     Abstract: rt2x00 generic pci device routines.
0011  */
0012 
0013 #include <linux/dma-mapping.h>
0014 #include <linux/kernel.h>
0015 #include <linux/module.h>
0016 #include <linux/pci.h>
0017 #include <linux/slab.h>
0018 
0019 #include "rt2x00.h"
0020 #include "rt2x00pci.h"
0021 
0022 /*
0023  * PCI driver handlers.
0024  */
0025 static void rt2x00pci_free_reg(struct rt2x00_dev *rt2x00dev)
0026 {
0027     kfree(rt2x00dev->rf);
0028     rt2x00dev->rf = NULL;
0029 
0030     kfree(rt2x00dev->eeprom);
0031     rt2x00dev->eeprom = NULL;
0032 
0033     if (rt2x00dev->csr.base) {
0034         iounmap(rt2x00dev->csr.base);
0035         rt2x00dev->csr.base = NULL;
0036     }
0037 }
0038 
0039 static int rt2x00pci_alloc_reg(struct rt2x00_dev *rt2x00dev)
0040 {
0041     struct pci_dev *pci_dev = to_pci_dev(rt2x00dev->dev);
0042 
0043     rt2x00dev->csr.base = pci_ioremap_bar(pci_dev, 0);
0044     if (!rt2x00dev->csr.base)
0045         goto exit;
0046 
0047     rt2x00dev->eeprom = kzalloc(rt2x00dev->ops->eeprom_size, GFP_KERNEL);
0048     if (!rt2x00dev->eeprom)
0049         goto exit;
0050 
0051     rt2x00dev->rf = kzalloc(rt2x00dev->ops->rf_size, GFP_KERNEL);
0052     if (!rt2x00dev->rf)
0053         goto exit;
0054 
0055     return 0;
0056 
0057 exit:
0058     rt2x00_probe_err("Failed to allocate registers\n");
0059 
0060     rt2x00pci_free_reg(rt2x00dev);
0061 
0062     return -ENOMEM;
0063 }
0064 
0065 int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops)
0066 {
0067     struct ieee80211_hw *hw;
0068     struct rt2x00_dev *rt2x00dev;
0069     int retval;
0070     u16 chip;
0071 
0072     retval = pci_enable_device(pci_dev);
0073     if (retval) {
0074         rt2x00_probe_err("Enable device failed\n");
0075         return retval;
0076     }
0077 
0078     retval = pci_request_regions(pci_dev, pci_name(pci_dev));
0079     if (retval) {
0080         rt2x00_probe_err("PCI request regions failed\n");
0081         goto exit_disable_device;
0082     }
0083 
0084     pci_set_master(pci_dev);
0085 
0086     if (pci_set_mwi(pci_dev))
0087         rt2x00_probe_err("MWI not available\n");
0088 
0089     if (dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(32))) {
0090         rt2x00_probe_err("PCI DMA not supported\n");
0091         retval = -EIO;
0092         goto exit_release_regions;
0093     }
0094 
0095     hw = ieee80211_alloc_hw(sizeof(struct rt2x00_dev), ops->hw);
0096     if (!hw) {
0097         rt2x00_probe_err("Failed to allocate hardware\n");
0098         retval = -ENOMEM;
0099         goto exit_release_regions;
0100     }
0101 
0102     pci_set_drvdata(pci_dev, hw);
0103 
0104     rt2x00dev = hw->priv;
0105     rt2x00dev->dev = &pci_dev->dev;
0106     rt2x00dev->ops = ops;
0107     rt2x00dev->hw = hw;
0108     rt2x00dev->irq = pci_dev->irq;
0109     rt2x00dev->name = ops->name;
0110 
0111     if (pci_is_pcie(pci_dev))
0112         rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCIE);
0113     else
0114         rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI);
0115 
0116     retval = rt2x00pci_alloc_reg(rt2x00dev);
0117     if (retval)
0118         goto exit_free_device;
0119 
0120     /*
0121      * Because rt3290 chip use different efuse offset to read efuse data.
0122      * So before read efuse it need to indicate it is the
0123      * rt3290 or not.
0124      */
0125     pci_read_config_word(pci_dev, PCI_DEVICE_ID, &chip);
0126     rt2x00dev->chip.rt = chip;
0127 
0128     retval = rt2x00lib_probe_dev(rt2x00dev);
0129     if (retval)
0130         goto exit_free_reg;
0131 
0132     return 0;
0133 
0134 exit_free_reg:
0135     rt2x00pci_free_reg(rt2x00dev);
0136 
0137 exit_free_device:
0138     ieee80211_free_hw(hw);
0139 
0140 exit_release_regions:
0141     pci_clear_mwi(pci_dev);
0142     pci_release_regions(pci_dev);
0143 
0144 exit_disable_device:
0145     pci_disable_device(pci_dev);
0146 
0147     return retval;
0148 }
0149 EXPORT_SYMBOL_GPL(rt2x00pci_probe);
0150 
0151 void rt2x00pci_remove(struct pci_dev *pci_dev)
0152 {
0153     struct ieee80211_hw *hw = pci_get_drvdata(pci_dev);
0154     struct rt2x00_dev *rt2x00dev = hw->priv;
0155 
0156     /*
0157      * Free all allocated data.
0158      */
0159     rt2x00lib_remove_dev(rt2x00dev);
0160     rt2x00pci_free_reg(rt2x00dev);
0161     ieee80211_free_hw(hw);
0162 
0163     /*
0164      * Free the PCI device data.
0165      */
0166     pci_clear_mwi(pci_dev);
0167     pci_disable_device(pci_dev);
0168     pci_release_regions(pci_dev);
0169 }
0170 EXPORT_SYMBOL_GPL(rt2x00pci_remove);
0171 
0172 static int __maybe_unused rt2x00pci_suspend(struct device *dev)
0173 {
0174     struct ieee80211_hw *hw = dev_get_drvdata(dev);
0175     struct rt2x00_dev *rt2x00dev = hw->priv;
0176 
0177     return rt2x00lib_suspend(rt2x00dev);
0178 }
0179 
0180 static int __maybe_unused rt2x00pci_resume(struct device *dev)
0181 {
0182     struct ieee80211_hw *hw = dev_get_drvdata(dev);
0183     struct rt2x00_dev *rt2x00dev = hw->priv;
0184 
0185     return rt2x00lib_resume(rt2x00dev);
0186 }
0187 
0188 SIMPLE_DEV_PM_OPS(rt2x00pci_pm_ops, rt2x00pci_suspend, rt2x00pci_resume);
0189 EXPORT_SYMBOL_GPL(rt2x00pci_pm_ops);
0190 
0191 /*
0192  * rt2x00pci module information.
0193  */
0194 MODULE_AUTHOR(DRV_PROJECT);
0195 MODULE_VERSION(DRV_VERSION);
0196 MODULE_DESCRIPTION("rt2x00 pci library");
0197 MODULE_LICENSE("GPL");