aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2x00dev.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-06-29 01:57:58 -0400
committerDavid S. Miller <davem@davemloft.net>2008-06-29 01:57:58 -0400
commit28f49d8fec19833672a6a813bfde0068fee50bc9 (patch)
tree6905c5cabc063e44b891ae0af5b5d7cce69e6e71 /drivers/net/wireless/rt2x00/rt2x00dev.c
parent332e4af80d1214fbf0e263e1408fc7c5b64ecdd6 (diff)
parentff28bd94e307c67abb1bccda5d3a9018bd798e08 (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00dev.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c100
1 files changed, 80 insertions, 20 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index cc4fee105ed6..ae8ab71fe474 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -469,12 +469,19 @@ static void rt2x00lib_intf_scheduled(struct work_struct *work)
469static void rt2x00lib_beacondone_iter(void *data, u8 *mac, 469static void rt2x00lib_beacondone_iter(void *data, u8 *mac,
470 struct ieee80211_vif *vif) 470 struct ieee80211_vif *vif)
471{ 471{
472 struct rt2x00_dev *rt2x00dev = data;
472 struct rt2x00_intf *intf = vif_to_intf(vif); 473 struct rt2x00_intf *intf = vif_to_intf(vif);
473 474
474 if (vif->type != IEEE80211_IF_TYPE_AP && 475 if (vif->type != IEEE80211_IF_TYPE_AP &&
475 vif->type != IEEE80211_IF_TYPE_IBSS) 476 vif->type != IEEE80211_IF_TYPE_IBSS)
476 return; 477 return;
477 478
479 /*
480 * Clean up the beacon skb.
481 */
482 rt2x00queue_free_skb(rt2x00dev, intf->beacon->skb);
483 intf->beacon->skb = NULL;
484
478 spin_lock(&intf->lock); 485 spin_lock(&intf->lock);
479 intf->delayed_flags |= DELAYED_UPDATE_BEACON; 486 intf->delayed_flags |= DELAYED_UPDATE_BEACON;
480 spin_unlock(&intf->lock); 487 spin_unlock(&intf->lock);
@@ -498,6 +505,12 @@ void rt2x00lib_txdone(struct queue_entry *entry,
498{ 505{
499 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 506 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
500 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); 507 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
508 enum data_queue_qid qid = skb_get_queue_mapping(entry->skb);
509
510 /*
511 * Unmap the skb.
512 */
513 rt2x00queue_unmap_skb(rt2x00dev, entry->skb);
501 514
502 /* 515 /*
503 * Send frame to debugfs immediately, after this call is completed 516 * Send frame to debugfs immediately, after this call is completed
@@ -546,39 +559,77 @@ void rt2x00lib_txdone(struct queue_entry *entry,
546 ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb); 559 ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb);
547 else 560 else
548 dev_kfree_skb_irq(entry->skb); 561 dev_kfree_skb_irq(entry->skb);
562
563 /*
564 * Make this entry available for reuse.
565 */
549 entry->skb = NULL; 566 entry->skb = NULL;
567 entry->flags = 0;
568
569 rt2x00dev->ops->lib->init_txentry(rt2x00dev, entry);
570
571 __clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
572 rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
573
574 /*
575 * If the data queue was below the threshold before the txdone
576 * handler we must make sure the packet queue in the mac80211 stack
577 * is reenabled when the txdone handler has finished.
578 */
579 if (!rt2x00queue_threshold(entry->queue))
580 ieee80211_wake_queue(rt2x00dev->hw, qid);
550} 581}
551EXPORT_SYMBOL_GPL(rt2x00lib_txdone); 582EXPORT_SYMBOL_GPL(rt2x00lib_txdone);
552 583
553void rt2x00lib_rxdone(struct queue_entry *entry, 584void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
554 struct rxdone_entry_desc *rxdesc) 585 struct queue_entry *entry)
555{ 586{
556 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 587 struct rxdone_entry_desc rxdesc;
588 struct sk_buff *skb;
557 struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; 589 struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status;
558 unsigned int header_size = ieee80211_get_hdrlen_from_skb(entry->skb);
559 struct ieee80211_supported_band *sband; 590 struct ieee80211_supported_band *sband;
560 struct ieee80211_hdr *hdr; 591 struct ieee80211_hdr *hdr;
561 const struct rt2x00_rate *rate; 592 const struct rt2x00_rate *rate;
593 unsigned int header_size;
562 unsigned int align; 594 unsigned int align;
563 unsigned int i; 595 unsigned int i;
564 int idx = -1; 596 int idx = -1;
565 u16 fc; 597
598 /*
599 * Allocate a new sk_buffer. If no new buffer available, drop the
600 * received frame and reuse the existing buffer.
601 */
602 skb = rt2x00queue_alloc_rxskb(rt2x00dev, entry);
603 if (!skb)
604 return;
605
606 /*
607 * Unmap the skb.
608 */
609 rt2x00queue_unmap_skb(rt2x00dev, entry->skb);
610
611 /*
612 * Extract the RXD details.
613 */
614 memset(&rxdesc, 0, sizeof(rxdesc));
615 rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc);
566 616
567 /* 617 /*
568 * The data behind the ieee80211 header must be 618 * The data behind the ieee80211 header must be
569 * aligned on a 4 byte boundary. 619 * aligned on a 4 byte boundary.
570 */ 620 */
621 header_size = ieee80211_get_hdrlen_from_skb(entry->skb);
571 align = ((unsigned long)(entry->skb->data + header_size)) & 3; 622 align = ((unsigned long)(entry->skb->data + header_size)) & 3;
572 623
573 if (align) { 624 if (align) {
574 skb_push(entry->skb, align); 625 skb_push(entry->skb, align);
575 /* Move entire frame in 1 command */ 626 /* Move entire frame in 1 command */
576 memmove(entry->skb->data, entry->skb->data + align, 627 memmove(entry->skb->data, entry->skb->data + align,
577 rxdesc->size); 628 rxdesc.size);
578 } 629 }
579 630
580 /* Update data pointers, trim buffer to correct size */ 631 /* Update data pointers, trim buffer to correct size */
581 skb_trim(entry->skb, rxdesc->size); 632 skb_trim(entry->skb, rxdesc.size);
582 633
583 /* 634 /*
584 * Update RX statistics. 635 * Update RX statistics.
@@ -587,10 +638,10 @@ void rt2x00lib_rxdone(struct queue_entry *entry,
587 for (i = 0; i < sband->n_bitrates; i++) { 638 for (i = 0; i < sband->n_bitrates; i++) {
588 rate = rt2x00_get_rate(sband->bitrates[i].hw_value); 639 rate = rt2x00_get_rate(sband->bitrates[i].hw_value);
589 640
590 if (((rxdesc->dev_flags & RXDONE_SIGNAL_PLCP) && 641 if (((rxdesc.dev_flags & RXDONE_SIGNAL_PLCP) &&
591 (rate->plcp == rxdesc->signal)) || 642 (rate->plcp == rxdesc.signal)) ||
592 (!(rxdesc->dev_flags & RXDONE_SIGNAL_PLCP) && 643 (!(rxdesc.dev_flags & RXDONE_SIGNAL_PLCP) &&
593 (rate->bitrate == rxdesc->signal))) { 644 (rate->bitrate == rxdesc.signal))) {
594 idx = i; 645 idx = i;
595 break; 646 break;
596 } 647 }
@@ -598,8 +649,8 @@ void rt2x00lib_rxdone(struct queue_entry *entry,
598 649
599 if (idx < 0) { 650 if (idx < 0) {
600 WARNING(rt2x00dev, "Frame received with unrecognized signal," 651 WARNING(rt2x00dev, "Frame received with unrecognized signal,"
601 "signal=0x%.2x, plcp=%d.\n", rxdesc->signal, 652 "signal=0x%.2x, plcp=%d.\n", rxdesc.signal,
602 !!(rxdesc->dev_flags & RXDONE_SIGNAL_PLCP)); 653 !!(rxdesc.dev_flags & RXDONE_SIGNAL_PLCP));
603 idx = 0; 654 idx = 0;
604 } 655 }
605 656
@@ -607,17 +658,17 @@ void rt2x00lib_rxdone(struct queue_entry *entry,
607 * Only update link status if this is a beacon frame carrying our bssid. 658 * Only update link status if this is a beacon frame carrying our bssid.
608 */ 659 */
609 hdr = (struct ieee80211_hdr *)entry->skb->data; 660 hdr = (struct ieee80211_hdr *)entry->skb->data;
610 fc = le16_to_cpu(hdr->frame_control); 661 if (ieee80211_is_beacon(hdr->frame_control) &&
611 if (is_beacon(fc) && (rxdesc->dev_flags & RXDONE_MY_BSS)) 662 (rxdesc.dev_flags & RXDONE_MY_BSS))
612 rt2x00lib_update_link_stats(&rt2x00dev->link, rxdesc->rssi); 663 rt2x00lib_update_link_stats(&rt2x00dev->link, rxdesc.rssi);
613 664
614 rt2x00dev->link.qual.rx_success++; 665 rt2x00dev->link.qual.rx_success++;
615 666
616 rx_status->rate_idx = idx; 667 rx_status->rate_idx = idx;
617 rx_status->qual = 668 rx_status->qual =
618 rt2x00lib_calculate_link_signal(rt2x00dev, rxdesc->rssi); 669 rt2x00lib_calculate_link_signal(rt2x00dev, rxdesc.rssi);
619 rx_status->signal = rxdesc->rssi; 670 rx_status->signal = rxdesc.rssi;
620 rx_status->flag = rxdesc->flags; 671 rx_status->flag = rxdesc.flags;
621 rx_status->antenna = rt2x00dev->link.ant.active.rx; 672 rx_status->antenna = rt2x00dev->link.ant.active.rx;
622 673
623 /* 674 /*
@@ -626,7 +677,16 @@ void rt2x00lib_rxdone(struct queue_entry *entry,
626 */ 677 */
627 rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb); 678 rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb);
628 ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb, rx_status); 679 ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb, rx_status);
629 entry->skb = NULL; 680
681 /*
682 * Replace the skb with the freshly allocated one.
683 */
684 entry->skb = skb;
685 entry->flags = 0;
686
687 rt2x00dev->ops->lib->init_rxentry(rt2x00dev, entry);
688
689 rt2x00queue_index_inc(entry->queue, Q_INDEX);
630} 690}
631EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); 691EXPORT_SYMBOL_GPL(rt2x00lib_rxdone);
632 692