aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/p54/p54pci.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-02-04 11:58:14 -0500
committerDavid S. Miller <davem@davemloft.net>2010-02-04 11:58:14 -0500
commit10be7eb36b93364b98688831ee7d26f58402bb96 (patch)
treeeb13ae80fcaa8baacd804a721c5a4962a501a2a4 /drivers/net/wireless/p54/p54pci.c
parent90c30335a70e96b8b8493b7deb15e6b30e6d9fce (diff)
parent5ffaf8a361b4c9025963959a744f21d8173c7669 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'drivers/net/wireless/p54/p54pci.c')
-rw-r--r--drivers/net/wireless/p54/p54pci.c74
1 files changed, 41 insertions, 33 deletions
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c
index 57c646598062..ed4bdffdd63e 100644
--- a/drivers/net/wireless/p54/p54pci.c
+++ b/drivers/net/wireless/p54/p54pci.c
@@ -157,6 +157,14 @@ static void p54p_refill_rx_ring(struct ieee80211_hw *dev,
157 skb_tail_pointer(skb), 157 skb_tail_pointer(skb),
158 priv->common.rx_mtu + 32, 158 priv->common.rx_mtu + 32,
159 PCI_DMA_FROMDEVICE); 159 PCI_DMA_FROMDEVICE);
160
161 if (pci_dma_mapping_error(priv->pdev, mapping)) {
162 dev_kfree_skb_any(skb);
163 dev_err(&priv->pdev->dev,
164 "RX DMA Mapping error\n");
165 break;
166 }
167
160 desc->host_addr = cpu_to_le32(mapping); 168 desc->host_addr = cpu_to_le32(mapping);
161 desc->device_addr = 0; // FIXME: necessary? 169 desc->device_addr = 0; // FIXME: necessary?
162 desc->len = cpu_to_le16(priv->common.rx_mtu + 32); 170 desc->len = cpu_to_le16(priv->common.rx_mtu + 32);
@@ -226,14 +234,14 @@ static void p54p_check_rx_ring(struct ieee80211_hw *dev, u32 *index,
226 p54p_refill_rx_ring(dev, ring_index, ring, ring_limit, rx_buf); 234 p54p_refill_rx_ring(dev, ring_index, ring, ring_limit, rx_buf);
227} 235}
228 236
229/* caller must hold priv->lock */
230static void p54p_check_tx_ring(struct ieee80211_hw *dev, u32 *index, 237static void p54p_check_tx_ring(struct ieee80211_hw *dev, u32 *index,
231 int ring_index, struct p54p_desc *ring, u32 ring_limit, 238 int ring_index, struct p54p_desc *ring, u32 ring_limit,
232 void **tx_buf) 239 struct sk_buff **tx_buf)
233{ 240{
234 struct p54p_priv *priv = dev->priv; 241 struct p54p_priv *priv = dev->priv;
235 struct p54p_ring_control *ring_control = priv->ring_control; 242 struct p54p_ring_control *ring_control = priv->ring_control;
236 struct p54p_desc *desc; 243 struct p54p_desc *desc;
244 struct sk_buff *skb;
237 u32 idx, i; 245 u32 idx, i;
238 246
239 i = (*index) % ring_limit; 247 i = (*index) % ring_limit;
@@ -242,9 +250,8 @@ static void p54p_check_tx_ring(struct ieee80211_hw *dev, u32 *index,
242 250
243 while (i != idx) { 251 while (i != idx) {
244 desc = &ring[i]; 252 desc = &ring[i];
245 if (tx_buf[i]) 253
246 if (FREE_AFTER_TX((struct sk_buff *) tx_buf[i])) 254 skb = tx_buf[i];
247 p54_free_skb(dev, tx_buf[i]);
248 tx_buf[i] = NULL; 255 tx_buf[i] = NULL;
249 256
250 pci_unmap_single(priv->pdev, le32_to_cpu(desc->host_addr), 257 pci_unmap_single(priv->pdev, le32_to_cpu(desc->host_addr),
@@ -255,17 +262,28 @@ static void p54p_check_tx_ring(struct ieee80211_hw *dev, u32 *index,
255 desc->len = 0; 262 desc->len = 0;
256 desc->flags = 0; 263 desc->flags = 0;
257 264
265 if (skb && FREE_AFTER_TX(skb))
266 p54_free_skb(dev, skb);
267
258 i++; 268 i++;
259 i %= ring_limit; 269 i %= ring_limit;
260 } 270 }
261} 271}
262 272
263static void p54p_rx_tasklet(unsigned long dev_id) 273static void p54p_tasklet(unsigned long dev_id)
264{ 274{
265 struct ieee80211_hw *dev = (struct ieee80211_hw *)dev_id; 275 struct ieee80211_hw *dev = (struct ieee80211_hw *)dev_id;
266 struct p54p_priv *priv = dev->priv; 276 struct p54p_priv *priv = dev->priv;
267 struct p54p_ring_control *ring_control = priv->ring_control; 277 struct p54p_ring_control *ring_control = priv->ring_control;
268 278
279 p54p_check_tx_ring(dev, &priv->tx_idx_mgmt, 3, ring_control->tx_mgmt,
280 ARRAY_SIZE(ring_control->tx_mgmt),
281 priv->tx_buf_mgmt);
282
283 p54p_check_tx_ring(dev, &priv->tx_idx_data, 1, ring_control->tx_data,
284 ARRAY_SIZE(ring_control->tx_data),
285 priv->tx_buf_data);
286
269 p54p_check_rx_ring(dev, &priv->rx_idx_mgmt, 2, ring_control->rx_mgmt, 287 p54p_check_rx_ring(dev, &priv->rx_idx_mgmt, 2, ring_control->rx_mgmt,
270 ARRAY_SIZE(ring_control->rx_mgmt), priv->rx_buf_mgmt); 288 ARRAY_SIZE(ring_control->rx_mgmt), priv->rx_buf_mgmt);
271 289
@@ -280,59 +298,49 @@ static irqreturn_t p54p_interrupt(int irq, void *dev_id)
280{ 298{
281 struct ieee80211_hw *dev = dev_id; 299 struct ieee80211_hw *dev = dev_id;
282 struct p54p_priv *priv = dev->priv; 300 struct p54p_priv *priv = dev->priv;
283 struct p54p_ring_control *ring_control = priv->ring_control;
284 __le32 reg; 301 __le32 reg;
285 302
286 spin_lock(&priv->lock);
287 reg = P54P_READ(int_ident); 303 reg = P54P_READ(int_ident);
288 if (unlikely(reg == cpu_to_le32(0xFFFFFFFF))) { 304 if (unlikely(reg == cpu_to_le32(0xFFFFFFFF))) {
289 spin_unlock(&priv->lock); 305 goto out;
290 return IRQ_HANDLED;
291 } 306 }
292
293 P54P_WRITE(int_ack, reg); 307 P54P_WRITE(int_ack, reg);
294 308
295 reg &= P54P_READ(int_enable); 309 reg &= P54P_READ(int_enable);
296 310
297 if (reg & cpu_to_le32(ISL38XX_INT_IDENT_UPDATE)) { 311 if (reg & cpu_to_le32(ISL38XX_INT_IDENT_UPDATE))
298 p54p_check_tx_ring(dev, &priv->tx_idx_mgmt, 312 tasklet_schedule(&priv->tasklet);
299 3, ring_control->tx_mgmt, 313 else if (reg & cpu_to_le32(ISL38XX_INT_IDENT_INIT))
300 ARRAY_SIZE(ring_control->tx_mgmt),
301 priv->tx_buf_mgmt);
302
303 p54p_check_tx_ring(dev, &priv->tx_idx_data,
304 1, ring_control->tx_data,
305 ARRAY_SIZE(ring_control->tx_data),
306 priv->tx_buf_data);
307
308 tasklet_schedule(&priv->rx_tasklet);
309
310 } else if (reg & cpu_to_le32(ISL38XX_INT_IDENT_INIT))
311 complete(&priv->boot_comp); 314 complete(&priv->boot_comp);
312 315
313 spin_unlock(&priv->lock); 316out:
314
315 return reg ? IRQ_HANDLED : IRQ_NONE; 317 return reg ? IRQ_HANDLED : IRQ_NONE;
316} 318}
317 319
318static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb) 320static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
319{ 321{
322 unsigned long flags;
320 struct p54p_priv *priv = dev->priv; 323 struct p54p_priv *priv = dev->priv;
321 struct p54p_ring_control *ring_control = priv->ring_control; 324 struct p54p_ring_control *ring_control = priv->ring_control;
322 unsigned long flags;
323 struct p54p_desc *desc; 325 struct p54p_desc *desc;
324 dma_addr_t mapping; 326 dma_addr_t mapping;
325 u32 device_idx, idx, i; 327 u32 device_idx, idx, i;
326 328
327 spin_lock_irqsave(&priv->lock, flags); 329 spin_lock_irqsave(&priv->lock, flags);
328
329 device_idx = le32_to_cpu(ring_control->device_idx[1]); 330 device_idx = le32_to_cpu(ring_control->device_idx[1]);
330 idx = le32_to_cpu(ring_control->host_idx[1]); 331 idx = le32_to_cpu(ring_control->host_idx[1]);
331 i = idx % ARRAY_SIZE(ring_control->tx_data); 332 i = idx % ARRAY_SIZE(ring_control->tx_data);
332 333
333 priv->tx_buf_data[i] = skb;
334 mapping = pci_map_single(priv->pdev, skb->data, skb->len, 334 mapping = pci_map_single(priv->pdev, skb->data, skb->len,
335 PCI_DMA_TODEVICE); 335 PCI_DMA_TODEVICE);
336 if (pci_dma_mapping_error(priv->pdev, mapping)) {
337 spin_unlock_irqrestore(&priv->lock, flags);
338 p54_free_skb(dev, skb);
339 dev_err(&priv->pdev->dev, "TX DMA mapping error\n");
340 return ;
341 }
342 priv->tx_buf_data[i] = skb;
343
336 desc = &ring_control->tx_data[i]; 344 desc = &ring_control->tx_data[i];
337 desc->host_addr = cpu_to_le32(mapping); 345 desc->host_addr = cpu_to_le32(mapping);
338 desc->device_addr = ((struct p54_hdr *)skb->data)->req_id; 346 desc->device_addr = ((struct p54_hdr *)skb->data)->req_id;
@@ -354,14 +362,14 @@ static void p54p_stop(struct ieee80211_hw *dev)
354 unsigned int i; 362 unsigned int i;
355 struct p54p_desc *desc; 363 struct p54p_desc *desc;
356 364
357 tasklet_kill(&priv->rx_tasklet);
358
359 P54P_WRITE(int_enable, cpu_to_le32(0)); 365 P54P_WRITE(int_enable, cpu_to_le32(0));
360 P54P_READ(int_enable); 366 P54P_READ(int_enable);
361 udelay(10); 367 udelay(10);
362 368
363 free_irq(priv->pdev->irq, dev); 369 free_irq(priv->pdev->irq, dev);
364 370
371 tasklet_kill(&priv->tasklet);
372
365 P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_RESET)); 373 P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_RESET));
366 374
367 for (i = 0; i < ARRAY_SIZE(priv->rx_buf_data); i++) { 375 for (i = 0; i < ARRAY_SIZE(priv->rx_buf_data); i++) {
@@ -545,7 +553,7 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
545 priv->common.tx = p54p_tx; 553 priv->common.tx = p54p_tx;
546 554
547 spin_lock_init(&priv->lock); 555 spin_lock_init(&priv->lock);
548 tasklet_init(&priv->rx_tasklet, p54p_rx_tasklet, (unsigned long)dev); 556 tasklet_init(&priv->tasklet, p54p_tasklet, (unsigned long)dev);
549 557
550 err = request_firmware(&priv->firmware, "isl3886pci", 558 err = request_firmware(&priv->firmware, "isl3886pci",
551 &priv->pdev->dev); 559 &priv->pdev->dev);