Linux Audio

Check our new training course

Loading...
v6.8
  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");
v4.17
 
  1/*
  2	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
  3	<http://rt2x00.serialmonkey.com>
  4
  5	This program is free software; you can redistribute it and/or modify
  6	it under the terms of the GNU General Public License as published by
  7	the Free Software Foundation; either version 2 of the License, or
  8	(at your option) any later version.
  9
 10	This program is distributed in the hope that it will be useful,
 11	but WITHOUT ANY WARRANTY; without even the implied warranty of
 12	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 13	GNU General Public License for more details.
 14
 15	You should have received a copy of the GNU General Public License
 16	along with this program; if not, see <http://www.gnu.org/licenses/>.
 17 */
 18
 19/*
 20	Module: rt2x00pci
 21	Abstract: rt2x00 generic pci device routines.
 22 */
 23
 24#include <linux/dma-mapping.h>
 25#include <linux/kernel.h>
 26#include <linux/module.h>
 27#include <linux/pci.h>
 28#include <linux/slab.h>
 29
 30#include "rt2x00.h"
 31#include "rt2x00pci.h"
 32
 33/*
 34 * PCI driver handlers.
 35 */
 36static void rt2x00pci_free_reg(struct rt2x00_dev *rt2x00dev)
 37{
 38	kfree(rt2x00dev->rf);
 39	rt2x00dev->rf = NULL;
 40
 41	kfree(rt2x00dev->eeprom);
 42	rt2x00dev->eeprom = NULL;
 43
 44	if (rt2x00dev->csr.base) {
 45		iounmap(rt2x00dev->csr.base);
 46		rt2x00dev->csr.base = NULL;
 47	}
 48}
 49
 50static int rt2x00pci_alloc_reg(struct rt2x00_dev *rt2x00dev)
 51{
 52	struct pci_dev *pci_dev = to_pci_dev(rt2x00dev->dev);
 53
 54	rt2x00dev->csr.base = pci_ioremap_bar(pci_dev, 0);
 55	if (!rt2x00dev->csr.base)
 56		goto exit;
 57
 58	rt2x00dev->eeprom = kzalloc(rt2x00dev->ops->eeprom_size, GFP_KERNEL);
 59	if (!rt2x00dev->eeprom)
 60		goto exit;
 61
 62	rt2x00dev->rf = kzalloc(rt2x00dev->ops->rf_size, GFP_KERNEL);
 63	if (!rt2x00dev->rf)
 64		goto exit;
 65
 66	return 0;
 67
 68exit:
 69	rt2x00_probe_err("Failed to allocate registers\n");
 70
 71	rt2x00pci_free_reg(rt2x00dev);
 72
 73	return -ENOMEM;
 74}
 75
 76int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops)
 77{
 78	struct ieee80211_hw *hw;
 79	struct rt2x00_dev *rt2x00dev;
 80	int retval;
 81	u16 chip;
 82
 83	retval = pci_enable_device(pci_dev);
 84	if (retval) {
 85		rt2x00_probe_err("Enable device failed\n");
 86		return retval;
 87	}
 88
 89	retval = pci_request_regions(pci_dev, pci_name(pci_dev));
 90	if (retval) {
 91		rt2x00_probe_err("PCI request regions failed\n");
 92		goto exit_disable_device;
 93	}
 94
 95	pci_set_master(pci_dev);
 96
 97	if (pci_set_mwi(pci_dev))
 98		rt2x00_probe_err("MWI not available\n");
 99
100	if (dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(32))) {
101		rt2x00_probe_err("PCI DMA not supported\n");
102		retval = -EIO;
103		goto exit_release_regions;
104	}
105
106	hw = ieee80211_alloc_hw(sizeof(struct rt2x00_dev), ops->hw);
107	if (!hw) {
108		rt2x00_probe_err("Failed to allocate hardware\n");
109		retval = -ENOMEM;
110		goto exit_release_regions;
111	}
112
113	pci_set_drvdata(pci_dev, hw);
114
115	rt2x00dev = hw->priv;
116	rt2x00dev->dev = &pci_dev->dev;
117	rt2x00dev->ops = ops;
118	rt2x00dev->hw = hw;
119	rt2x00dev->irq = pci_dev->irq;
120	rt2x00dev->name = ops->name;
121
122	if (pci_is_pcie(pci_dev))
123		rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCIE);
124	else
125		rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI);
126
127	retval = rt2x00pci_alloc_reg(rt2x00dev);
128	if (retval)
129		goto exit_free_device;
130
131	/*
132	 * Because rt3290 chip use different efuse offset to read efuse data.
133	 * So before read efuse it need to indicate it is the
134	 * rt3290 or not.
135	 */
136	pci_read_config_word(pci_dev, PCI_DEVICE_ID, &chip);
137	rt2x00dev->chip.rt = chip;
138
139	retval = rt2x00lib_probe_dev(rt2x00dev);
140	if (retval)
141		goto exit_free_reg;
142
143	return 0;
144
145exit_free_reg:
146	rt2x00pci_free_reg(rt2x00dev);
147
148exit_free_device:
149	ieee80211_free_hw(hw);
150
151exit_release_regions:
152	pci_clear_mwi(pci_dev);
153	pci_release_regions(pci_dev);
154
155exit_disable_device:
156	pci_disable_device(pci_dev);
157
158	return retval;
159}
160EXPORT_SYMBOL_GPL(rt2x00pci_probe);
161
162void rt2x00pci_remove(struct pci_dev *pci_dev)
163{
164	struct ieee80211_hw *hw = pci_get_drvdata(pci_dev);
165	struct rt2x00_dev *rt2x00dev = hw->priv;
166
167	/*
168	 * Free all allocated data.
169	 */
170	rt2x00lib_remove_dev(rt2x00dev);
171	rt2x00pci_free_reg(rt2x00dev);
172	ieee80211_free_hw(hw);
173
174	/*
175	 * Free the PCI device data.
176	 */
177	pci_clear_mwi(pci_dev);
178	pci_disable_device(pci_dev);
179	pci_release_regions(pci_dev);
180}
181EXPORT_SYMBOL_GPL(rt2x00pci_remove);
182
183#ifdef CONFIG_PM
184int rt2x00pci_suspend(struct pci_dev *pci_dev, pm_message_t state)
185{
186	struct ieee80211_hw *hw = pci_get_drvdata(pci_dev);
187	struct rt2x00_dev *rt2x00dev = hw->priv;
188	int retval;
189
190	retval = rt2x00lib_suspend(rt2x00dev, state);
191	if (retval)
192		return retval;
193
194	pci_save_state(pci_dev);
195	pci_disable_device(pci_dev);
196	return pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state));
197}
198EXPORT_SYMBOL_GPL(rt2x00pci_suspend);
199
200int rt2x00pci_resume(struct pci_dev *pci_dev)
201{
202	struct ieee80211_hw *hw = pci_get_drvdata(pci_dev);
203	struct rt2x00_dev *rt2x00dev = hw->priv;
204
205	if (pci_set_power_state(pci_dev, PCI_D0) ||
206	    pci_enable_device(pci_dev)) {
207		rt2x00_err(rt2x00dev, "Failed to resume device\n");
208		return -EIO;
209	}
210
211	pci_restore_state(pci_dev);
212	return rt2x00lib_resume(rt2x00dev);
213}
214EXPORT_SYMBOL_GPL(rt2x00pci_resume);
215#endif /* CONFIG_PM */
 
216
217/*
218 * rt2x00pci module information.
219 */
220MODULE_AUTHOR(DRV_PROJECT);
221MODULE_VERSION(DRV_VERSION);
222MODULE_DESCRIPTION("rt2x00 pci library");
223MODULE_LICENSE("GPL");