aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGabor Juhos <juhosg@openwrt.org>2013-03-29 10:52:27 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-04-03 14:50:06 -0400
commit69a2bac8984c4e6dba78b330ed183fd580c65e99 (patch)
tree80d6cf2c5217f035a38ce43143ffc0e587e56f98
parent83589b30f1e1dc9898986293c9336b8ce1705dec (diff)
rt2x00: rt2x00pci: fix build error on Ralink RT3x5x SoCs
The rt2800pci driver supports the built-in wireless MAC of the Ralink RT3x5x SoCs. However building the driver for these SoCs leads to the following error: LD init/built-in.o drivers/built-in.o: In function `rt2800pci_rxdone_tasklet': <...>/drivers/net/wireless/rt2x00/rt2800pci.c:1012: undefined reference to `rt2x00pci_rxdone' drivers/built-in.o:(.rodata+0x4780): undefined reference to `rt2x00pci_initialize' drivers/built-in.o:(.rodata+0x4784): undefined reference to `rt2x00pci_uninitialize' drivers/built-in.o:(.rodata+0x47bc): undefined reference to `rt2x00pci_flush_queue' drivers/built-in.o:(.rodata+0x4818): undefined reference to `rt2x00pci_regbusy_read' make[5]: *** [vmlinux] Error 1 The missing functions are provided by the rt2x00pci module. This module is only selected by the rt2800pci driver if PCI support is enabled in the kernel, because some parts of the rt2x00pci code depends on PCI support. PCI support is not available on the RT3x5x SoCs because those have no PCI host controller at all. Move the non PCI specific code from rt2x00pci into a separate module. This makes it possible to use that code even if PCI support is disabled. The affected functions are used by all of the rt2x00 PCI drivers so select the new module for those drivers. Signed-off-by: Gabor Juhos <juhosg@openwrt.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/rt2x00/Kconfig7
-rw-r--r--drivers/net/wireless/rt2x00/Makefile1
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mmio.c216
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mmio.h119
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c176
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.h88
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c1
10 files changed, 347 insertions, 264 deletions
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig
index 2bf4efa33186..76cd47eb901e 100644
--- a/drivers/net/wireless/rt2x00/Kconfig
+++ b/drivers/net/wireless/rt2x00/Kconfig
@@ -20,6 +20,7 @@ if RT2X00
20config RT2400PCI 20config RT2400PCI
21 tristate "Ralink rt2400 (PCI/PCMCIA) support" 21 tristate "Ralink rt2400 (PCI/PCMCIA) support"
22 depends on PCI 22 depends on PCI
23 select RT2X00_LIB_MMIO
23 select RT2X00_LIB_PCI 24 select RT2X00_LIB_PCI
24 select EEPROM_93CX6 25 select EEPROM_93CX6
25 ---help--- 26 ---help---
@@ -31,6 +32,7 @@ config RT2400PCI
31config RT2500PCI 32config RT2500PCI
32 tristate "Ralink rt2500 (PCI/PCMCIA) support" 33 tristate "Ralink rt2500 (PCI/PCMCIA) support"
33 depends on PCI 34 depends on PCI
35 select RT2X00_LIB_MMIO
34 select RT2X00_LIB_PCI 36 select RT2X00_LIB_PCI
35 select EEPROM_93CX6 37 select EEPROM_93CX6
36 ---help--- 38 ---help---
@@ -43,6 +45,7 @@ config RT61PCI
43 tristate "Ralink rt2501/rt61 (PCI/PCMCIA) support" 45 tristate "Ralink rt2501/rt61 (PCI/PCMCIA) support"
44 depends on PCI 46 depends on PCI
45 select RT2X00_LIB_PCI 47 select RT2X00_LIB_PCI
48 select RT2X00_LIB_MMIO
46 select RT2X00_LIB_FIRMWARE 49 select RT2X00_LIB_FIRMWARE
47 select RT2X00_LIB_CRYPTO 50 select RT2X00_LIB_CRYPTO
48 select CRC_ITU_T 51 select CRC_ITU_T
@@ -57,6 +60,7 @@ config RT2800PCI
57 tristate "Ralink rt27xx/rt28xx/rt30xx (PCI/PCIe/PCMCIA) support" 60 tristate "Ralink rt27xx/rt28xx/rt30xx (PCI/PCIe/PCMCIA) support"
58 depends on PCI || SOC_RT288X || SOC_RT305X 61 depends on PCI || SOC_RT288X || SOC_RT305X
59 select RT2800_LIB 62 select RT2800_LIB
63 select RT2X00_LIB_MMIO
60 select RT2X00_LIB_PCI if PCI 64 select RT2X00_LIB_PCI if PCI
61 select RT2X00_LIB_SOC if SOC_RT288X || SOC_RT305X 65 select RT2X00_LIB_SOC if SOC_RT288X || SOC_RT305X
62 select RT2X00_LIB_FIRMWARE 66 select RT2X00_LIB_FIRMWARE
@@ -185,6 +189,9 @@ endif
185config RT2800_LIB 189config RT2800_LIB
186 tristate 190 tristate
187 191
192config RT2X00_LIB_MMIO
193 tristate
194
188config RT2X00_LIB_PCI 195config RT2X00_LIB_PCI
189 tristate 196 tristate
190 select RT2X00_LIB 197 select RT2X00_LIB
diff --git a/drivers/net/wireless/rt2x00/Makefile b/drivers/net/wireless/rt2x00/Makefile
index 349d5b8284a4..f069d8bc5b67 100644
--- a/drivers/net/wireless/rt2x00/Makefile
+++ b/drivers/net/wireless/rt2x00/Makefile
@@ -9,6 +9,7 @@ rt2x00lib-$(CONFIG_RT2X00_LIB_FIRMWARE) += rt2x00firmware.o
9rt2x00lib-$(CONFIG_RT2X00_LIB_LEDS) += rt2x00leds.o 9rt2x00lib-$(CONFIG_RT2X00_LIB_LEDS) += rt2x00leds.o
10 10
11obj-$(CONFIG_RT2X00_LIB) += rt2x00lib.o 11obj-$(CONFIG_RT2X00_LIB) += rt2x00lib.o
12obj-$(CONFIG_RT2X00_LIB_MMIO) += rt2x00mmio.o
12obj-$(CONFIG_RT2X00_LIB_PCI) += rt2x00pci.o 13obj-$(CONFIG_RT2X00_LIB_PCI) += rt2x00pci.o
13obj-$(CONFIG_RT2X00_LIB_SOC) += rt2x00soc.o 14obj-$(CONFIG_RT2X00_LIB_SOC) += rt2x00soc.o
14obj-$(CONFIG_RT2X00_LIB_USB) += rt2x00usb.o 15obj-$(CONFIG_RT2X00_LIB_USB) += rt2x00usb.o
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 221beaaa83f1..dcfb54e0c516 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -34,6 +34,7 @@
34#include <linux/slab.h> 34#include <linux/slab.h>
35 35
36#include "rt2x00.h" 36#include "rt2x00.h"
37#include "rt2x00mmio.h"
37#include "rt2x00pci.h" 38#include "rt2x00pci.h"
38#include "rt2400pci.h" 39#include "rt2400pci.h"
39 40
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 39edc59e8d03..e1d2dc9ed28a 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -34,6 +34,7 @@
34#include <linux/slab.h> 34#include <linux/slab.h>
35 35
36#include "rt2x00.h" 36#include "rt2x00.h"
37#include "rt2x00mmio.h"
37#include "rt2x00pci.h" 38#include "rt2x00pci.h"
38#include "rt2500pci.h" 39#include "rt2500pci.h"
39 40
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index ded73da4de0b..ba5a05625aaa 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -41,6 +41,7 @@
41#include <linux/eeprom_93cx6.h> 41#include <linux/eeprom_93cx6.h>
42 42
43#include "rt2x00.h" 43#include "rt2x00.h"
44#include "rt2x00mmio.h"
44#include "rt2x00pci.h" 45#include "rt2x00pci.h"
45#include "rt2x00soc.h" 46#include "rt2x00soc.h"
46#include "rt2800lib.h" 47#include "rt2800lib.h"
diff --git a/drivers/net/wireless/rt2x00/rt2x00mmio.c b/drivers/net/wireless/rt2x00/rt2x00mmio.c
new file mode 100644
index 000000000000..d84a680ba0c9
--- /dev/null
+++ b/drivers/net/wireless/rt2x00/rt2x00mmio.c
@@ -0,0 +1,216 @@
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, write to the
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21/*
22 Module: rt2x00mmio
23 Abstract: rt2x00 generic mmio device routines.
24 */
25
26#include <linux/dma-mapping.h>
27#include <linux/kernel.h>
28#include <linux/module.h>
29#include <linux/slab.h>
30
31#include "rt2x00.h"
32#include "rt2x00mmio.h"
33
34/*
35 * Register access.
36 */
37int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev,
38 const unsigned int offset,
39 const struct rt2x00_field32 field,
40 u32 *reg)
41{
42 unsigned int i;
43
44 if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
45 return 0;
46
47 for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
48 rt2x00pci_register_read(rt2x00dev, offset, reg);
49 if (!rt2x00_get_field32(*reg, field))
50 return 1;
51 udelay(REGISTER_BUSY_DELAY);
52 }
53
54 printk_once(KERN_ERR "%s() Indirect register access failed: "
55 "offset=0x%.08x, value=0x%.08x\n", __func__, offset, *reg);
56 *reg = ~0;
57
58 return 0;
59}
60EXPORT_SYMBOL_GPL(rt2x00pci_regbusy_read);
61
62bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
63{
64 struct data_queue *queue = rt2x00dev->rx;
65 struct queue_entry *entry;
66 struct queue_entry_priv_pci *entry_priv;
67 struct skb_frame_desc *skbdesc;
68 int max_rx = 16;
69
70 while (--max_rx) {
71 entry = rt2x00queue_get_entry(queue, Q_INDEX);
72 entry_priv = entry->priv_data;
73
74 if (rt2x00dev->ops->lib->get_entry_state(entry))
75 break;
76
77 /*
78 * Fill in desc fields of the skb descriptor
79 */
80 skbdesc = get_skb_frame_desc(entry->skb);
81 skbdesc->desc = entry_priv->desc;
82 skbdesc->desc_len = entry->queue->desc_size;
83
84 /*
85 * DMA is already done, notify rt2x00lib that
86 * it finished successfully.
87 */
88 rt2x00lib_dmastart(entry);
89 rt2x00lib_dmadone(entry);
90
91 /*
92 * Send the frame to rt2x00lib for further processing.
93 */
94 rt2x00lib_rxdone(entry, GFP_ATOMIC);
95 }
96
97 return !max_rx;
98}
99EXPORT_SYMBOL_GPL(rt2x00pci_rxdone);
100
101void rt2x00pci_flush_queue(struct data_queue *queue, bool drop)
102{
103 unsigned int i;
104
105 for (i = 0; !rt2x00queue_empty(queue) && i < 10; i++)
106 msleep(10);
107}
108EXPORT_SYMBOL_GPL(rt2x00pci_flush_queue);
109
110/*
111 * Device initialization handlers.
112 */
113static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev,
114 struct data_queue *queue)
115{
116 struct queue_entry_priv_pci *entry_priv;
117 void *addr;
118 dma_addr_t dma;
119 unsigned int i;
120
121 /*
122 * Allocate DMA memory for descriptor and buffer.
123 */
124 addr = dma_alloc_coherent(rt2x00dev->dev,
125 queue->limit * queue->desc_size,
126 &dma, GFP_KERNEL);
127 if (!addr)
128 return -ENOMEM;
129
130 memset(addr, 0, queue->limit * queue->desc_size);
131
132 /*
133 * Initialize all queue entries to contain valid addresses.
134 */
135 for (i = 0; i < queue->limit; i++) {
136 entry_priv = queue->entries[i].priv_data;
137 entry_priv->desc = addr + i * queue->desc_size;
138 entry_priv->desc_dma = dma + i * queue->desc_size;
139 }
140
141 return 0;
142}
143
144static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev,
145 struct data_queue *queue)
146{
147 struct queue_entry_priv_pci *entry_priv =
148 queue->entries[0].priv_data;
149
150 if (entry_priv->desc)
151 dma_free_coherent(rt2x00dev->dev,
152 queue->limit * queue->desc_size,
153 entry_priv->desc, entry_priv->desc_dma);
154 entry_priv->desc = NULL;
155}
156
157int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev)
158{
159 struct data_queue *queue;
160 int status;
161
162 /*
163 * Allocate DMA
164 */
165 queue_for_each(rt2x00dev, queue) {
166 status = rt2x00pci_alloc_queue_dma(rt2x00dev, queue);
167 if (status)
168 goto exit;
169 }
170
171 /*
172 * Register interrupt handler.
173 */
174 status = request_irq(rt2x00dev->irq,
175 rt2x00dev->ops->lib->irq_handler,
176 IRQF_SHARED, rt2x00dev->name, rt2x00dev);
177 if (status) {
178 ERROR(rt2x00dev, "IRQ %d allocation failed (error %d).\n",
179 rt2x00dev->irq, status);
180 goto exit;
181 }
182
183 return 0;
184
185exit:
186 queue_for_each(rt2x00dev, queue)
187 rt2x00pci_free_queue_dma(rt2x00dev, queue);
188
189 return status;
190}
191EXPORT_SYMBOL_GPL(rt2x00pci_initialize);
192
193void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev)
194{
195 struct data_queue *queue;
196
197 /*
198 * Free irq line.
199 */
200 free_irq(rt2x00dev->irq, rt2x00dev);
201
202 /*
203 * Free DMA
204 */
205 queue_for_each(rt2x00dev, queue)
206 rt2x00pci_free_queue_dma(rt2x00dev, queue);
207}
208EXPORT_SYMBOL_GPL(rt2x00pci_uninitialize);
209
210/*
211 * rt2x00mmio module information.
212 */
213MODULE_AUTHOR(DRV_PROJECT);
214MODULE_VERSION(DRV_VERSION);
215MODULE_DESCRIPTION("rt2x00 mmio library");
216MODULE_LICENSE("GPL");
diff --git a/drivers/net/wireless/rt2x00/rt2x00mmio.h b/drivers/net/wireless/rt2x00/rt2x00mmio.h
new file mode 100644
index 000000000000..4ecaf60175bf
--- /dev/null
+++ b/drivers/net/wireless/rt2x00/rt2x00mmio.h
@@ -0,0 +1,119 @@
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, write to the
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21/*
22 Module: rt2x00mmio
23 Abstract: Data structures for the rt2x00mmio module.
24 */
25
26#ifndef RT2X00MMIO_H
27#define RT2X00MMIO_H
28
29#include <linux/io.h>
30
31/*
32 * Register access.
33 */
34static inline void rt2x00pci_register_read(struct rt2x00_dev *rt2x00dev,
35 const unsigned int offset,
36 u32 *value)
37{
38 *value = readl(rt2x00dev->csr.base + offset);
39}
40
41static inline void rt2x00pci_register_multiread(struct rt2x00_dev *rt2x00dev,
42 const unsigned int offset,
43 void *value, const u32 length)
44{
45 memcpy_fromio(value, rt2x00dev->csr.base + offset, length);
46}
47
48static inline void rt2x00pci_register_write(struct rt2x00_dev *rt2x00dev,
49 const unsigned int offset,
50 u32 value)
51{
52 writel(value, rt2x00dev->csr.base + offset);
53}
54
55static inline void rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev,
56 const unsigned int offset,
57 const void *value,
58 const u32 length)
59{
60 __iowrite32_copy(rt2x00dev->csr.base + offset, value, length >> 2);
61}
62
63/**
64 * rt2x00pci_regbusy_read - Read from register with busy check
65 * @rt2x00dev: Device pointer, see &struct rt2x00_dev.
66 * @offset: Register offset
67 * @field: Field to check if register is busy
68 * @reg: Pointer to where register contents should be stored
69 *
70 * This function will read the given register, and checks if the
71 * register is busy. If it is, it will sleep for a couple of
72 * microseconds before reading the register again. If the register
73 * is not read after a certain timeout, this function will return
74 * FALSE.
75 */
76int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev,
77 const unsigned int offset,
78 const struct rt2x00_field32 field,
79 u32 *reg);
80
81/**
82 * struct queue_entry_priv_pci: Per entry PCI specific information
83 *
84 * @desc: Pointer to device descriptor
85 * @desc_dma: DMA pointer to &desc.
86 * @data: Pointer to device's entry memory.
87 * @data_dma: DMA pointer to &data.
88 */
89struct queue_entry_priv_pci {
90 __le32 *desc;
91 dma_addr_t desc_dma;
92};
93
94/**
95 * rt2x00pci_rxdone - Handle RX done events
96 * @rt2x00dev: Device pointer, see &struct rt2x00_dev.
97 *
98 * Returns true if there are still rx frames pending and false if all
99 * pending rx frames were processed.
100 */
101bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev);
102
103/**
104 * rt2x00pci_flush_queue - Flush data queue
105 * @queue: Data queue to stop
106 * @drop: True to drop all pending frames.
107 *
108 * This will wait for a maximum of 100ms, waiting for the queues
109 * to become empty.
110 */
111void rt2x00pci_flush_queue(struct data_queue *queue, bool drop);
112
113/*
114 * Device initialization handlers.
115 */
116int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev);
117void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev);
118
119#endif /* RT2X00MMIO_H */
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index b1c673ecada1..e87865e33113 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -33,182 +33,6 @@
33#include "rt2x00pci.h" 33#include "rt2x00pci.h"
34 34
35/* 35/*
36 * Register access.
37 */
38int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev,
39 const unsigned int offset,
40 const struct rt2x00_field32 field,
41 u32 *reg)
42{
43 unsigned int i;
44
45 if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
46 return 0;
47
48 for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
49 rt2x00pci_register_read(rt2x00dev, offset, reg);
50 if (!rt2x00_get_field32(*reg, field))
51 return 1;
52 udelay(REGISTER_BUSY_DELAY);
53 }
54
55 printk_once(KERN_ERR "%s() Indirect register access failed: "
56 "offset=0x%.08x, value=0x%.08x\n", __func__, offset, *reg);
57 *reg = ~0;
58
59 return 0;
60}
61EXPORT_SYMBOL_GPL(rt2x00pci_regbusy_read);
62
63bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
64{
65 struct data_queue *queue = rt2x00dev->rx;
66 struct queue_entry *entry;
67 struct queue_entry_priv_pci *entry_priv;
68 struct skb_frame_desc *skbdesc;
69 int max_rx = 16;
70
71 while (--max_rx) {
72 entry = rt2x00queue_get_entry(queue, Q_INDEX);
73 entry_priv = entry->priv_data;
74
75 if (rt2x00dev->ops->lib->get_entry_state(entry))
76 break;
77
78 /*
79 * Fill in desc fields of the skb descriptor
80 */
81 skbdesc = get_skb_frame_desc(entry->skb);
82 skbdesc->desc = entry_priv->desc;
83 skbdesc->desc_len = entry->queue->desc_size;
84
85 /*
86 * DMA is already done, notify rt2x00lib that
87 * it finished successfully.
88 */
89 rt2x00lib_dmastart(entry);
90 rt2x00lib_dmadone(entry);
91
92 /*
93 * Send the frame to rt2x00lib for further processing.
94 */
95 rt2x00lib_rxdone(entry, GFP_ATOMIC);
96 }
97
98 return !max_rx;
99}
100EXPORT_SYMBOL_GPL(rt2x00pci_rxdone);
101
102void rt2x00pci_flush_queue(struct data_queue *queue, bool drop)
103{
104 unsigned int i;
105
106 for (i = 0; !rt2x00queue_empty(queue) && i < 10; i++)
107 msleep(10);
108}
109EXPORT_SYMBOL_GPL(rt2x00pci_flush_queue);
110
111/*
112 * Device initialization handlers.
113 */
114static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev,
115 struct data_queue *queue)
116{
117 struct queue_entry_priv_pci *entry_priv;
118 void *addr;
119 dma_addr_t dma;
120 unsigned int i;
121
122 /*
123 * Allocate DMA memory for descriptor and buffer.
124 */
125 addr = dma_alloc_coherent(rt2x00dev->dev,
126 queue->limit * queue->desc_size,
127 &dma, GFP_KERNEL);
128 if (!addr)
129 return -ENOMEM;
130
131 memset(addr, 0, queue->limit * queue->desc_size);
132
133 /*
134 * Initialize all queue entries to contain valid addresses.
135 */
136 for (i = 0; i < queue->limit; i++) {
137 entry_priv = queue->entries[i].priv_data;
138 entry_priv->desc = addr + i * queue->desc_size;
139 entry_priv->desc_dma = dma + i * queue->desc_size;
140 }
141
142 return 0;
143}
144
145static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev,
146 struct data_queue *queue)
147{
148 struct queue_entry_priv_pci *entry_priv =
149 queue->entries[0].priv_data;
150
151 if (entry_priv->desc)
152 dma_free_coherent(rt2x00dev->dev,
153 queue->limit * queue->desc_size,
154 entry_priv->desc, entry_priv->desc_dma);
155 entry_priv->desc = NULL;
156}
157
158int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev)
159{
160 struct data_queue *queue;
161 int status;
162
163 /*
164 * Allocate DMA
165 */
166 queue_for_each(rt2x00dev, queue) {
167 status = rt2x00pci_alloc_queue_dma(rt2x00dev, queue);
168 if (status)
169 goto exit;
170 }
171
172 /*
173 * Register interrupt handler.
174 */
175 status = request_irq(rt2x00dev->irq,
176 rt2x00dev->ops->lib->irq_handler,
177 IRQF_SHARED, rt2x00dev->name, rt2x00dev);
178 if (status) {
179 ERROR(rt2x00dev, "IRQ %d allocation failed (error %d).\n",
180 rt2x00dev->irq, status);
181 goto exit;
182 }
183
184 return 0;
185
186exit:
187 queue_for_each(rt2x00dev, queue)
188 rt2x00pci_free_queue_dma(rt2x00dev, queue);
189
190 return status;
191}
192EXPORT_SYMBOL_GPL(rt2x00pci_initialize);
193
194void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev)
195{
196 struct data_queue *queue;
197
198 /*
199 * Free irq line.
200 */
201 free_irq(rt2x00dev->irq, rt2x00dev);
202
203 /*
204 * Free DMA
205 */
206 queue_for_each(rt2x00dev, queue)
207 rt2x00pci_free_queue_dma(rt2x00dev, queue);
208}
209EXPORT_SYMBOL_GPL(rt2x00pci_uninitialize);
210
211/*
212 * PCI driver handlers. 36 * PCI driver handlers.
213 */ 37 */
214static void rt2x00pci_free_reg(struct rt2x00_dev *rt2x00dev) 38static void rt2x00pci_free_reg(struct rt2x00_dev *rt2x00dev)
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h
index e2c99f2b9a14..60d90b20f8b9 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.h
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.h
@@ -36,94 +36,6 @@
36#define PCI_DEVICE_DATA(__ops) .driver_data = (kernel_ulong_t)(__ops) 36#define PCI_DEVICE_DATA(__ops) .driver_data = (kernel_ulong_t)(__ops)
37 37
38/* 38/*
39 * Register access.
40 */
41static inline void rt2x00pci_register_read(struct rt2x00_dev *rt2x00dev,
42 const unsigned int offset,
43 u32 *value)
44{
45 *value = readl(rt2x00dev->csr.base + offset);
46}
47
48static inline void rt2x00pci_register_multiread(struct rt2x00_dev *rt2x00dev,
49 const unsigned int offset,
50 void *value, const u32 length)
51{
52 memcpy_fromio(value, rt2x00dev->csr.base + offset, length);
53}
54
55static inline void rt2x00pci_register_write(struct rt2x00_dev *rt2x00dev,
56 const unsigned int offset,
57 u32 value)
58{
59 writel(value, rt2x00dev->csr.base + offset);
60}
61
62static inline void rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev,
63 const unsigned int offset,
64 const void *value,
65 const u32 length)
66{
67 __iowrite32_copy(rt2x00dev->csr.base + offset, value, length >> 2);
68}
69
70/**
71 * rt2x00pci_regbusy_read - Read from register with busy check
72 * @rt2x00dev: Device pointer, see &struct rt2x00_dev.
73 * @offset: Register offset
74 * @field: Field to check if register is busy
75 * @reg: Pointer to where register contents should be stored
76 *
77 * This function will read the given register, and checks if the
78 * register is busy. If it is, it will sleep for a couple of
79 * microseconds before reading the register again. If the register
80 * is not read after a certain timeout, this function will return
81 * FALSE.
82 */
83int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev,
84 const unsigned int offset,
85 const struct rt2x00_field32 field,
86 u32 *reg);
87
88/**
89 * struct queue_entry_priv_pci: Per entry PCI specific information
90 *
91 * @desc: Pointer to device descriptor
92 * @desc_dma: DMA pointer to &desc.
93 * @data: Pointer to device's entry memory.
94 * @data_dma: DMA pointer to &data.
95 */
96struct queue_entry_priv_pci {
97 __le32 *desc;
98 dma_addr_t desc_dma;
99};
100
101/**
102 * rt2x00pci_rxdone - Handle RX done events
103 * @rt2x00dev: Device pointer, see &struct rt2x00_dev.
104 *
105 * Returns true if there are still rx frames pending and false if all
106 * pending rx frames were processed.
107 */
108bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev);
109
110/**
111 * rt2x00pci_flush_queue - Flush data queue
112 * @queue: Data queue to stop
113 * @drop: True to drop all pending frames.
114 *
115 * This will wait for a maximum of 100ms, waiting for the queues
116 * to become empty.
117 */
118void rt2x00pci_flush_queue(struct data_queue *queue, bool drop);
119
120/*
121 * Device initialization handlers.
122 */
123int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev);
124void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev);
125
126/*
127 * PCI driver handlers. 39 * PCI driver handlers.
128 */ 40 */
129int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops); 41int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops);
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index f95792cfcf89..9e3c8ff53e3f 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -35,6 +35,7 @@
35#include <linux/eeprom_93cx6.h> 35#include <linux/eeprom_93cx6.h>
36 36
37#include "rt2x00.h" 37#include "rt2x00.h"
38#include "rt2x00mmio.h"
38#include "rt2x00pci.h" 39#include "rt2x00pci.h"
39#include "rt61pci.h" 40#include "rt61pci.h"
40 41