aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorChristian Lamparter <chunkeey@googlemail.com>2010-10-29 18:36:53 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-11-15 13:25:35 -0500
commit3eedb6f436858f3e864139dc184adc9a51440c92 (patch)
tree85367b42ac609cffd673c18940a498bf9a4af3cb /drivers/net/wireless
parent2a6cef513fab525399e484edc9bfb39b6d462f76 (diff)
carl9170: configurable beacon rates
Previously, the beacon rate was fixed to either: * 1Mb/s [2.4GHz band] * 6Mb/s [5GHz band] This limitation has been addressed and now the beacon rate is selected by ieee80211_tx_info's rate control info, almost like any ordinary data frame. Signed-off-by: Christian Lamparter <chunkeey@googlemail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/ath/carl9170/mac.c52
1 files changed, 32 insertions, 20 deletions
diff --git a/drivers/net/wireless/ath/carl9170/mac.c b/drivers/net/wireless/ath/carl9170/mac.c
index c34eeeeb8af3..385cf508479b 100644
--- a/drivers/net/wireless/ath/carl9170/mac.c
+++ b/drivers/net/wireless/ath/carl9170/mac.c
@@ -457,8 +457,9 @@ int carl9170_set_beacon_timers(struct ar9170 *ar)
457 457
458int carl9170_update_beacon(struct ar9170 *ar, const bool submit) 458int carl9170_update_beacon(struct ar9170 *ar, const bool submit)
459{ 459{
460 struct sk_buff *skb; 460 struct sk_buff *skb = NULL;
461 struct carl9170_vif_info *cvif; 461 struct carl9170_vif_info *cvif;
462 struct ieee80211_tx_info *txinfo;
462 __le32 *data, *old = NULL; 463 __le32 *data, *old = NULL;
463 u32 word, off, addr, len; 464 u32 word, off, addr, len;
464 int i = 0, err = 0; 465 int i = 0, err = 0;
@@ -487,7 +488,13 @@ found:
487 488
488 if (!skb) { 489 if (!skb) {
489 err = -ENOMEM; 490 err = -ENOMEM;
490 goto out_unlock; 491 goto err_free;
492 }
493
494 txinfo = IEEE80211_SKB_CB(skb);
495 if (txinfo->control.rates[0].flags & IEEE80211_TX_RC_MCS) {
496 err = -EINVAL;
497 goto err_free;
491 } 498 }
492 499
493 spin_lock_bh(&ar->beacon_lock); 500 spin_lock_bh(&ar->beacon_lock);
@@ -504,11 +511,8 @@ found:
504 wiphy_err(ar->hw->wiphy, "beacon does not " 511 wiphy_err(ar->hw->wiphy, "beacon does not "
505 "fit into device memory!\n"); 512 "fit into device memory!\n");
506 } 513 }
507
508 spin_unlock_bh(&ar->beacon_lock);
509 dev_kfree_skb_any(skb);
510 err = -EINVAL; 514 err = -EINVAL;
511 goto out_unlock; 515 goto err_unlock;
512 } 516 }
513 517
514 if (len > AR9170_MAC_BCN_LENGTH_MAX) { 518 if (len > AR9170_MAC_BCN_LENGTH_MAX) {
@@ -518,22 +522,22 @@ found:
518 AR9170_MAC_BCN_LENGTH_MAX, len); 522 AR9170_MAC_BCN_LENGTH_MAX, len);
519 } 523 }
520 524
521 spin_unlock_bh(&ar->beacon_lock);
522 dev_kfree_skb_any(skb);
523 err = -EMSGSIZE; 525 err = -EMSGSIZE;
524 goto out_unlock; 526 goto err_unlock;
525 } 527 }
526 528
527 carl9170_async_regwrite_begin(ar); 529 i = txinfo->control.rates[0].idx;
530 if (txinfo->band != IEEE80211_BAND_2GHZ)
531 i += 4;
528 532
529 /* XXX: use skb->cb info */ 533 word = __carl9170_ratetable[i].hw_value & 0xf;
530 if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) { 534 if (i < 4)
531 carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP, 535 word |= ((skb->len + FCS_LEN) << (3 + 16)) + 0x0400;
532 ((skb->len + FCS_LEN) << (3 + 16)) + 0x0400); 536 else
533 } else { 537 word |= ((skb->len + FCS_LEN) << 16) + 0x0010;
534 carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP, 538
535 ((skb->len + FCS_LEN) << 16) + 0x001b); 539 carl9170_async_regwrite_begin(ar);
536 } 540 carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP, word);
537 541
538 for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) { 542 for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) {
539 /* 543 /*
@@ -557,7 +561,7 @@ found:
557 cvif->beacon = skb; 561 cvif->beacon = skb;
558 spin_unlock_bh(&ar->beacon_lock); 562 spin_unlock_bh(&ar->beacon_lock);
559 if (err) 563 if (err)
560 goto out_unlock; 564 goto err_free;
561 565
562 if (submit) { 566 if (submit) {
563 err = carl9170_bcn_ctrl(ar, cvif->id, 567 err = carl9170_bcn_ctrl(ar, cvif->id,
@@ -565,10 +569,18 @@ found:
565 addr, skb->len + FCS_LEN); 569 addr, skb->len + FCS_LEN);
566 570
567 if (err) 571 if (err)
568 goto out_unlock; 572 goto err_free;
569 } 573 }
570out_unlock: 574out_unlock:
571 rcu_read_unlock(); 575 rcu_read_unlock();
576 return 0;
577
578err_unlock:
579 spin_unlock_bh(&ar->beacon_lock);
580
581err_free:
582 rcu_read_unlock();
583 dev_kfree_skb_any(skb);
572 return err; 584 return err;
573} 585}
574 586