diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00pci.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00pci.c | 231 |
1 files changed, 44 insertions, 187 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 60893de3bf8f..adf2876ed8ab 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c | |||
@@ -34,44 +34,34 @@ | |||
34 | /* | 34 | /* |
35 | * TX data handlers. | 35 | * TX data handlers. |
36 | */ | 36 | */ |
37 | int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev, | 37 | int rt2x00pci_write_tx_data(struct queue_entry *entry) |
38 | struct data_queue *queue, struct sk_buff *skb, | ||
39 | struct ieee80211_tx_control *control) | ||
40 | { | 38 | { |
41 | struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); | 39 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; |
42 | struct queue_entry_priv_pci_tx *priv_tx = entry->priv_data; | ||
43 | struct skb_frame_desc *skbdesc; | 40 | struct skb_frame_desc *skbdesc; |
44 | u32 word; | 41 | u32 word; |
45 | 42 | ||
46 | if (rt2x00queue_full(queue)) | 43 | rt2x00_desc_read(entry_priv->desc, 0, &word); |
47 | return -EINVAL; | ||
48 | |||
49 | rt2x00_desc_read(priv_tx->desc, 0, &word); | ||
50 | 44 | ||
51 | if (rt2x00_get_field32(word, TXD_ENTRY_OWNER_NIC) || | 45 | /* |
52 | rt2x00_get_field32(word, TXD_ENTRY_VALID)) { | 46 | * This should not happen, we already checked the entry |
53 | ERROR(rt2x00dev, | 47 | * was ours. When the hardware disagrees there has been |
54 | "Arrived at non-free entry in the non-full queue %d.\n" | 48 | * a queue corruption! |
49 | */ | ||
50 | if (unlikely(rt2x00_get_field32(word, TXD_ENTRY_OWNER_NIC) || | ||
51 | rt2x00_get_field32(word, TXD_ENTRY_VALID))) { | ||
52 | ERROR(entry->queue->rt2x00dev, | ||
53 | "Corrupt queue %d, accessing entry which is not ours.\n" | ||
55 | "Please file bug report to %s.\n", | 54 | "Please file bug report to %s.\n", |
56 | control->queue, DRV_PROJECT); | 55 | entry->queue->qid, DRV_PROJECT); |
57 | return -EINVAL; | 56 | return -EINVAL; |
58 | } | 57 | } |
59 | 58 | ||
60 | /* | 59 | /* |
61 | * Fill in skb descriptor | 60 | * Fill in skb descriptor |
62 | */ | 61 | */ |
63 | skbdesc = get_skb_frame_desc(skb); | 62 | skbdesc = get_skb_frame_desc(entry->skb); |
64 | skbdesc->data = skb->data; | 63 | skbdesc->desc = entry_priv->desc; |
65 | skbdesc->data_len = skb->len; | 64 | skbdesc->desc_len = entry->queue->desc_size; |
66 | skbdesc->desc = priv_tx->desc; | ||
67 | skbdesc->desc_len = queue->desc_size; | ||
68 | skbdesc->entry = entry; | ||
69 | |||
70 | memcpy(&priv_tx->control, control, sizeof(priv_tx->control)); | ||
71 | memcpy(priv_tx->data, skb->data, skb->len); | ||
72 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | ||
73 | |||
74 | rt2x00queue_index_inc(queue, Q_INDEX); | ||
75 | 65 | ||
76 | return 0; | 66 | return 0; |
77 | } | 67 | } |
@@ -84,180 +74,62 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) | |||
84 | { | 74 | { |
85 | struct data_queue *queue = rt2x00dev->rx; | 75 | struct data_queue *queue = rt2x00dev->rx; |
86 | struct queue_entry *entry; | 76 | struct queue_entry *entry; |
87 | struct queue_entry_priv_pci_rx *priv_rx; | 77 | struct queue_entry_priv_pci *entry_priv; |
88 | struct ieee80211_hdr *hdr; | ||
89 | struct skb_frame_desc *skbdesc; | 78 | struct skb_frame_desc *skbdesc; |
90 | struct rxdone_entry_desc rxdesc; | ||
91 | int header_size; | ||
92 | int align; | ||
93 | u32 word; | 79 | u32 word; |
94 | 80 | ||
95 | while (1) { | 81 | while (1) { |
96 | entry = rt2x00queue_get_entry(queue, Q_INDEX); | 82 | entry = rt2x00queue_get_entry(queue, Q_INDEX); |
97 | priv_rx = entry->priv_data; | 83 | entry_priv = entry->priv_data; |
98 | rt2x00_desc_read(priv_rx->desc, 0, &word); | 84 | rt2x00_desc_read(entry_priv->desc, 0, &word); |
99 | 85 | ||
100 | if (rt2x00_get_field32(word, RXD_ENTRY_OWNER_NIC)) | 86 | if (rt2x00_get_field32(word, RXD_ENTRY_OWNER_NIC)) |
101 | break; | 87 | break; |
102 | 88 | ||
103 | memset(&rxdesc, 0, sizeof(rxdesc)); | ||
104 | rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); | ||
105 | |||
106 | hdr = (struct ieee80211_hdr *)priv_rx->data; | ||
107 | header_size = | ||
108 | ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control)); | ||
109 | |||
110 | /* | 89 | /* |
111 | * The data behind the ieee80211 header must be | 90 | * Fill in desc fields of the skb descriptor |
112 | * aligned on a 4 byte boundary. | ||
113 | */ | ||
114 | align = header_size % 4; | ||
115 | |||
116 | /* | ||
117 | * Allocate the sk_buffer, initialize it and copy | ||
118 | * all data into it. | ||
119 | */ | ||
120 | entry->skb = dev_alloc_skb(rxdesc.size + align); | ||
121 | if (!entry->skb) | ||
122 | return; | ||
123 | |||
124 | skb_reserve(entry->skb, align); | ||
125 | memcpy(skb_put(entry->skb, rxdesc.size), | ||
126 | priv_rx->data, rxdesc.size); | ||
127 | |||
128 | /* | ||
129 | * Fill in skb descriptor | ||
130 | */ | 91 | */ |
131 | skbdesc = get_skb_frame_desc(entry->skb); | 92 | skbdesc = get_skb_frame_desc(entry->skb); |
132 | memset(skbdesc, 0, sizeof(*skbdesc)); | 93 | skbdesc->desc = entry_priv->desc; |
133 | skbdesc->data = entry->skb->data; | 94 | skbdesc->desc_len = entry->queue->desc_size; |
134 | skbdesc->data_len = entry->skb->len; | ||
135 | skbdesc->desc = priv_rx->desc; | ||
136 | skbdesc->desc_len = queue->desc_size; | ||
137 | skbdesc->entry = entry; | ||
138 | 95 | ||
139 | /* | 96 | /* |
140 | * Send the frame to rt2x00lib for further processing. | 97 | * Send the frame to rt2x00lib for further processing. |
141 | */ | 98 | */ |
142 | rt2x00lib_rxdone(entry, &rxdesc); | 99 | rt2x00lib_rxdone(rt2x00dev, entry); |
143 | |||
144 | if (test_bit(DEVICE_ENABLED_RADIO, &queue->rt2x00dev->flags)) { | ||
145 | rt2x00_set_field32(&word, RXD_ENTRY_OWNER_NIC, 1); | ||
146 | rt2x00_desc_write(priv_rx->desc, 0, word); | ||
147 | } | ||
148 | |||
149 | rt2x00queue_index_inc(queue, Q_INDEX); | ||
150 | } | 100 | } |
151 | } | 101 | } |
152 | EXPORT_SYMBOL_GPL(rt2x00pci_rxdone); | 102 | EXPORT_SYMBOL_GPL(rt2x00pci_rxdone); |
153 | 103 | ||
154 | void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry, | ||
155 | struct txdone_entry_desc *txdesc) | ||
156 | { | ||
157 | struct queue_entry_priv_pci_tx *priv_tx = entry->priv_data; | ||
158 | u32 word; | ||
159 | |||
160 | txdesc->control = &priv_tx->control; | ||
161 | rt2x00lib_txdone(entry, txdesc); | ||
162 | |||
163 | /* | ||
164 | * Make this entry available for reuse. | ||
165 | */ | ||
166 | entry->flags = 0; | ||
167 | |||
168 | rt2x00_desc_read(priv_tx->desc, 0, &word); | ||
169 | rt2x00_set_field32(&word, TXD_ENTRY_OWNER_NIC, 0); | ||
170 | rt2x00_set_field32(&word, TXD_ENTRY_VALID, 0); | ||
171 | rt2x00_desc_write(priv_tx->desc, 0, word); | ||
172 | |||
173 | rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); | ||
174 | |||
175 | /* | ||
176 | * If the data queue was full before the txdone handler | ||
177 | * we must make sure the packet queue in the mac80211 stack | ||
178 | * is reenabled when the txdone handler has finished. | ||
179 | */ | ||
180 | if (!rt2x00queue_full(entry->queue)) | ||
181 | ieee80211_wake_queue(rt2x00dev->hw, priv_tx->control.queue); | ||
182 | |||
183 | } | ||
184 | EXPORT_SYMBOL_GPL(rt2x00pci_txdone); | ||
185 | |||
186 | /* | 104 | /* |
187 | * Device initialization handlers. | 105 | * Device initialization handlers. |
188 | */ | 106 | */ |
189 | #define desc_size(__queue) \ | ||
190 | ({ \ | ||
191 | ((__queue)->limit * (__queue)->desc_size);\ | ||
192 | }) | ||
193 | |||
194 | #define data_size(__queue) \ | ||
195 | ({ \ | ||
196 | ((__queue)->limit * (__queue)->data_size);\ | ||
197 | }) | ||
198 | |||
199 | #define dma_size(__queue) \ | ||
200 | ({ \ | ||
201 | data_size(__queue) + desc_size(__queue);\ | ||
202 | }) | ||
203 | |||
204 | #define desc_offset(__queue, __base, __i) \ | ||
205 | ({ \ | ||
206 | (__base) + data_size(__queue) + \ | ||
207 | ((__i) * (__queue)->desc_size); \ | ||
208 | }) | ||
209 | |||
210 | #define data_offset(__queue, __base, __i) \ | ||
211 | ({ \ | ||
212 | (__base) + \ | ||
213 | ((__i) * (__queue)->data_size); \ | ||
214 | }) | ||
215 | |||
216 | static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, | 107 | static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, |
217 | struct data_queue *queue) | 108 | struct data_queue *queue) |
218 | { | 109 | { |
219 | struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); | 110 | struct queue_entry_priv_pci *entry_priv; |
220 | struct queue_entry_priv_pci_rx *priv_rx; | ||
221 | struct queue_entry_priv_pci_tx *priv_tx; | ||
222 | void *addr; | 111 | void *addr; |
223 | dma_addr_t dma; | 112 | dma_addr_t dma; |
224 | void *desc_addr; | ||
225 | dma_addr_t desc_dma; | ||
226 | void *data_addr; | ||
227 | dma_addr_t data_dma; | ||
228 | unsigned int i; | 113 | unsigned int i; |
229 | 114 | ||
230 | /* | 115 | /* |
231 | * Allocate DMA memory for descriptor and buffer. | 116 | * Allocate DMA memory for descriptor and buffer. |
232 | */ | 117 | */ |
233 | addr = pci_alloc_consistent(pci_dev, dma_size(queue), &dma); | 118 | addr = dma_alloc_coherent(rt2x00dev->dev, |
119 | queue->limit * queue->desc_size, | ||
120 | &dma, GFP_KERNEL | GFP_DMA); | ||
234 | if (!addr) | 121 | if (!addr) |
235 | return -ENOMEM; | 122 | return -ENOMEM; |
236 | 123 | ||
237 | memset(addr, 0, dma_size(queue)); | 124 | memset(addr, 0, queue->limit * queue->desc_size); |
238 | 125 | ||
239 | /* | 126 | /* |
240 | * Initialize all queue entries to contain valid addresses. | 127 | * Initialize all queue entries to contain valid addresses. |
241 | */ | 128 | */ |
242 | for (i = 0; i < queue->limit; i++) { | 129 | for (i = 0; i < queue->limit; i++) { |
243 | desc_addr = desc_offset(queue, addr, i); | 130 | entry_priv = queue->entries[i].priv_data; |
244 | desc_dma = desc_offset(queue, dma, i); | 131 | entry_priv->desc = addr + i * queue->desc_size; |
245 | data_addr = data_offset(queue, addr, i); | 132 | entry_priv->desc_dma = dma + i * queue->desc_size; |
246 | data_dma = data_offset(queue, dma, i); | ||
247 | |||
248 | if (queue->qid == QID_RX) { | ||
249 | priv_rx = queue->entries[i].priv_data; | ||
250 | priv_rx->desc = desc_addr; | ||
251 | priv_rx->desc_dma = desc_dma; | ||
252 | priv_rx->data = data_addr; | ||
253 | priv_rx->data_dma = data_dma; | ||
254 | } else { | ||
255 | priv_tx = queue->entries[i].priv_data; | ||
256 | priv_tx->desc = desc_addr; | ||
257 | priv_tx->desc_dma = desc_dma; | ||
258 | priv_tx->data = data_addr; | ||
259 | priv_tx->data_dma = data_dma; | ||
260 | } | ||
261 | } | 133 | } |
262 | 134 | ||
263 | return 0; | 135 | return 0; |
@@ -266,34 +138,19 @@ static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, | |||
266 | static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev, | 138 | static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev, |
267 | struct data_queue *queue) | 139 | struct data_queue *queue) |
268 | { | 140 | { |
269 | struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); | 141 | struct queue_entry_priv_pci *entry_priv = |
270 | struct queue_entry_priv_pci_rx *priv_rx; | 142 | queue->entries[0].priv_data; |
271 | struct queue_entry_priv_pci_tx *priv_tx; | 143 | |
272 | void *data_addr; | 144 | if (entry_priv->desc) |
273 | dma_addr_t data_dma; | 145 | dma_free_coherent(rt2x00dev->dev, |
274 | 146 | queue->limit * queue->desc_size, | |
275 | if (queue->qid == QID_RX) { | 147 | entry_priv->desc, entry_priv->desc_dma); |
276 | priv_rx = queue->entries[0].priv_data; | 148 | entry_priv->desc = NULL; |
277 | data_addr = priv_rx->data; | ||
278 | data_dma = priv_rx->data_dma; | ||
279 | |||
280 | priv_rx->data = NULL; | ||
281 | } else { | ||
282 | priv_tx = queue->entries[0].priv_data; | ||
283 | data_addr = priv_tx->data; | ||
284 | data_dma = priv_tx->data_dma; | ||
285 | |||
286 | priv_tx->data = NULL; | ||
287 | } | ||
288 | |||
289 | if (data_addr) | ||
290 | pci_free_consistent(pci_dev, dma_size(queue), | ||
291 | data_addr, data_dma); | ||
292 | } | 149 | } |
293 | 150 | ||
294 | int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) | 151 | int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) |
295 | { | 152 | { |
296 | struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); | 153 | struct pci_dev *pci_dev = to_pci_dev(rt2x00dev->dev); |
297 | struct data_queue *queue; | 154 | struct data_queue *queue; |
298 | int status; | 155 | int status; |
299 | 156 | ||
@@ -334,7 +191,7 @@ void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev) | |||
334 | /* | 191 | /* |
335 | * Free irq line. | 192 | * Free irq line. |
336 | */ | 193 | */ |
337 | free_irq(rt2x00dev_pci(rt2x00dev)->irq, rt2x00dev); | 194 | free_irq(to_pci_dev(rt2x00dev->dev)->irq, rt2x00dev); |
338 | 195 | ||
339 | /* | 196 | /* |
340 | * Free DMA | 197 | * Free DMA |
@@ -363,7 +220,7 @@ static void rt2x00pci_free_reg(struct rt2x00_dev *rt2x00dev) | |||
363 | 220 | ||
364 | static int rt2x00pci_alloc_reg(struct rt2x00_dev *rt2x00dev) | 221 | static int rt2x00pci_alloc_reg(struct rt2x00_dev *rt2x00dev) |
365 | { | 222 | { |
366 | struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); | 223 | struct pci_dev *pci_dev = to_pci_dev(rt2x00dev->dev); |
367 | 224 | ||
368 | rt2x00dev->csr.base = ioremap(pci_resource_start(pci_dev, 0), | 225 | rt2x00dev->csr.base = ioremap(pci_resource_start(pci_dev, 0), |
369 | pci_resource_len(pci_dev, 0)); | 226 | pci_resource_len(pci_dev, 0)); |
@@ -412,7 +269,7 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) | |||
412 | if (pci_set_mwi(pci_dev)) | 269 | if (pci_set_mwi(pci_dev)) |
413 | ERROR_PROBE("MWI not available.\n"); | 270 | ERROR_PROBE("MWI not available.\n"); |
414 | 271 | ||
415 | if (pci_set_dma_mask(pci_dev, DMA_32BIT_MASK)) { | 272 | if (dma_set_mask(&pci_dev->dev, DMA_32BIT_MASK)) { |
416 | ERROR_PROBE("PCI DMA not supported.\n"); | 273 | ERROR_PROBE("PCI DMA not supported.\n"); |
417 | retval = -EIO; | 274 | retval = -EIO; |
418 | goto exit_disable_device; | 275 | goto exit_disable_device; |
@@ -428,7 +285,7 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) | |||
428 | pci_set_drvdata(pci_dev, hw); | 285 | pci_set_drvdata(pci_dev, hw); |
429 | 286 | ||
430 | rt2x00dev = hw->priv; | 287 | rt2x00dev = hw->priv; |
431 | rt2x00dev->dev = pci_dev; | 288 | rt2x00dev->dev = &pci_dev->dev; |
432 | rt2x00dev->ops = ops; | 289 | rt2x00dev->ops = ops; |
433 | rt2x00dev->hw = hw; | 290 | rt2x00dev->hw = hw; |
434 | 291 | ||