aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Lamparter <chunkeey@googlemail.com>2011-07-16 11:25:14 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-07-18 14:29:43 -0400
commit943c33996f9b0851c4122dc96cae08d4ba8debf0 (patch)
tree679bc1439f9c9e0867f4abc19ed0899ca792fab2
parent43b52a5ae9b56c02fbf6e2d7de3c50ebf9ff7973 (diff)
carl9170: move beacon_update into tx.c
Signed-off-by: Christian Lamparter <chunkeey@googlemail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/ath/carl9170/carl9170.h2
-rw-r--r--drivers/net/wireless/ath/carl9170/mac.c129
-rw-r--r--drivers/net/wireless/ath/carl9170/tx.c129
3 files changed, 130 insertions, 130 deletions
diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h
index f9a4655ea0b..d5c35fe2e89 100644
--- a/drivers/net/wireless/ath/carl9170/carl9170.h
+++ b/drivers/net/wireless/ath/carl9170/carl9170.h
@@ -532,7 +532,6 @@ int carl9170_set_ampdu_settings(struct ar9170 *ar);
532int carl9170_set_slot_time(struct ar9170 *ar); 532int carl9170_set_slot_time(struct ar9170 *ar);
533int carl9170_set_mac_rates(struct ar9170 *ar); 533int carl9170_set_mac_rates(struct ar9170 *ar);
534int carl9170_set_hwretry_limit(struct ar9170 *ar, const u32 max_retry); 534int carl9170_set_hwretry_limit(struct ar9170 *ar, const u32 max_retry);
535int carl9170_update_beacon(struct ar9170 *ar, const bool submit);
536int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac, 535int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac,
537 const u8 ktype, const u8 keyidx, const u8 *keydata, const int keylen); 536 const u8 ktype, const u8 keyidx, const u8 *keydata, const int keylen);
538int carl9170_disable_key(struct ar9170 *ar, const u8 id); 537int carl9170_disable_key(struct ar9170 *ar, const u8 id);
@@ -553,6 +552,7 @@ void carl9170_tx_drop(struct ar9170 *ar, struct sk_buff *skb);
553void carl9170_tx_scheduler(struct ar9170 *ar); 552void carl9170_tx_scheduler(struct ar9170 *ar);
554void carl9170_tx_get_skb(struct sk_buff *skb); 553void carl9170_tx_get_skb(struct sk_buff *skb);
555int carl9170_tx_put_skb(struct sk_buff *skb); 554int carl9170_tx_put_skb(struct sk_buff *skb);
555int carl9170_update_beacon(struct ar9170 *ar, const bool submit);
556 556
557/* LEDs */ 557/* LEDs */
558#ifdef CONFIG_CARL9170_LEDS 558#ifdef CONFIG_CARL9170_LEDS
diff --git a/drivers/net/wireless/ath/carl9170/mac.c b/drivers/net/wireless/ath/carl9170/mac.c
index 385cf508479..dfda9197099 100644
--- a/drivers/net/wireless/ath/carl9170/mac.c
+++ b/drivers/net/wireless/ath/carl9170/mac.c
@@ -455,135 +455,6 @@ int carl9170_set_beacon_timers(struct ar9170 *ar)
455 return carl9170_regwrite_result(); 455 return carl9170_regwrite_result();
456} 456}
457 457
458int carl9170_update_beacon(struct ar9170 *ar, const bool submit)
459{
460 struct sk_buff *skb = NULL;
461 struct carl9170_vif_info *cvif;
462 struct ieee80211_tx_info *txinfo;
463 __le32 *data, *old = NULL;
464 u32 word, off, addr, len;
465 int i = 0, err = 0;
466
467 rcu_read_lock();
468 cvif = rcu_dereference(ar->beacon_iter);
469retry:
470 if (ar->vifs == 0 || !cvif)
471 goto out_unlock;
472
473 list_for_each_entry_continue_rcu(cvif, &ar->vif_list, list) {
474 if (cvif->active && cvif->enable_beacon)
475 goto found;
476 }
477
478 if (!ar->beacon_enabled || i++)
479 goto out_unlock;
480
481 goto retry;
482
483found:
484 rcu_assign_pointer(ar->beacon_iter, cvif);
485
486 skb = ieee80211_beacon_get_tim(ar->hw, carl9170_get_vif(cvif),
487 NULL, NULL);
488
489 if (!skb) {
490 err = -ENOMEM;
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;
498 }
499
500 spin_lock_bh(&ar->beacon_lock);
501 data = (__le32 *)skb->data;
502 if (cvif->beacon)
503 old = (__le32 *)cvif->beacon->data;
504
505 off = cvif->id * AR9170_MAC_BCN_LENGTH_MAX;
506 addr = ar->fw.beacon_addr + off;
507 len = roundup(skb->len + FCS_LEN, 4);
508
509 if ((off + len) > ar->fw.beacon_max_len) {
510 if (net_ratelimit()) {
511 wiphy_err(ar->hw->wiphy, "beacon does not "
512 "fit into device memory!\n");
513 }
514 err = -EINVAL;
515 goto err_unlock;
516 }
517
518 if (len > AR9170_MAC_BCN_LENGTH_MAX) {
519 if (net_ratelimit()) {
520 wiphy_err(ar->hw->wiphy, "no support for beacons "
521 "bigger than %d (yours:%d).\n",
522 AR9170_MAC_BCN_LENGTH_MAX, len);
523 }
524
525 err = -EMSGSIZE;
526 goto err_unlock;
527 }
528
529 i = txinfo->control.rates[0].idx;
530 if (txinfo->band != IEEE80211_BAND_2GHZ)
531 i += 4;
532
533 word = __carl9170_ratetable[i].hw_value & 0xf;
534 if (i < 4)
535 word |= ((skb->len + FCS_LEN) << (3 + 16)) + 0x0400;
536 else
537 word |= ((skb->len + FCS_LEN) << 16) + 0x0010;
538
539 carl9170_async_regwrite_begin(ar);
540 carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP, word);
541
542 for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) {
543 /*
544 * XXX: This accesses beyond skb data for up
545 * to the last 3 bytes!!
546 */
547
548 if (old && (data[i] == old[i]))
549 continue;
550
551 word = le32_to_cpu(data[i]);
552 carl9170_async_regwrite(addr + 4 * i, word);
553 }
554 carl9170_async_regwrite_finish();
555
556 dev_kfree_skb_any(cvif->beacon);
557 cvif->beacon = NULL;
558
559 err = carl9170_async_regwrite_result();
560 if (!err)
561 cvif->beacon = skb;
562 spin_unlock_bh(&ar->beacon_lock);
563 if (err)
564 goto err_free;
565
566 if (submit) {
567 err = carl9170_bcn_ctrl(ar, cvif->id,
568 CARL9170_BCN_CTRL_CAB_TRIGGER,
569 addr, skb->len + FCS_LEN);
570
571 if (err)
572 goto err_free;
573 }
574out_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);
584 return err;
585}
586
587int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac, 458int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac,
588 const u8 ktype, const u8 keyidx, const u8 *keydata, 459 const u8 ktype, const u8 keyidx, const u8 *keydata,
589 const int keylen) 460 const int keylen)
diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c
index e94084fcf6f..0f8cdeffd64 100644
--- a/drivers/net/wireless/ath/carl9170/tx.c
+++ b/drivers/net/wireless/ath/carl9170/tx.c
@@ -1438,3 +1438,132 @@ void carl9170_tx_scheduler(struct ar9170 *ar)
1438 if (ar->tx_schedule) 1438 if (ar->tx_schedule)
1439 carl9170_tx(ar); 1439 carl9170_tx(ar);
1440} 1440}
1441
1442int carl9170_update_beacon(struct ar9170 *ar, const bool submit)
1443{
1444 struct sk_buff *skb = NULL;
1445 struct carl9170_vif_info *cvif;
1446 struct ieee80211_tx_info *txinfo;
1447 __le32 *data, *old = NULL;
1448 u32 word, off, addr, len;
1449 int i = 0, err = 0;
1450
1451 rcu_read_lock();
1452 cvif = rcu_dereference(ar->beacon_iter);
1453retry:
1454 if (ar->vifs == 0 || !cvif)
1455 goto out_unlock;
1456
1457 list_for_each_entry_continue_rcu(cvif, &ar->vif_list, list) {
1458 if (cvif->active && cvif->enable_beacon)
1459 goto found;
1460 }
1461
1462 if (!ar->beacon_enabled || i++)
1463 goto out_unlock;
1464
1465 goto retry;
1466
1467found:
1468 rcu_assign_pointer(ar->beacon_iter, cvif);
1469
1470 skb = ieee80211_beacon_get_tim(ar->hw, carl9170_get_vif(cvif),
1471 NULL, NULL);
1472
1473 if (!skb) {
1474 err = -ENOMEM;
1475 goto err_free;
1476 }
1477
1478 txinfo = IEEE80211_SKB_CB(skb);
1479 if (txinfo->control.rates[0].flags & IEEE80211_TX_RC_MCS) {
1480 err = -EINVAL;
1481 goto err_free;
1482 }
1483
1484 spin_lock_bh(&ar->beacon_lock);
1485 data = (__le32 *)skb->data;
1486 if (cvif->beacon)
1487 old = (__le32 *)cvif->beacon->data;
1488
1489 off = cvif->id * AR9170_MAC_BCN_LENGTH_MAX;
1490 addr = ar->fw.beacon_addr + off;
1491 len = roundup(skb->len + FCS_LEN, 4);
1492
1493 if ((off + len) > ar->fw.beacon_max_len) {
1494 if (net_ratelimit()) {
1495 wiphy_err(ar->hw->wiphy, "beacon does not "
1496 "fit into device memory!\n");
1497 }
1498 err = -EINVAL;
1499 goto err_unlock;
1500 }
1501
1502 if (len > AR9170_MAC_BCN_LENGTH_MAX) {
1503 if (net_ratelimit()) {
1504 wiphy_err(ar->hw->wiphy, "no support for beacons "
1505 "bigger than %d (yours:%d).\n",
1506 AR9170_MAC_BCN_LENGTH_MAX, len);
1507 }
1508
1509 err = -EMSGSIZE;
1510 goto err_unlock;
1511 }
1512
1513 i = txinfo->control.rates[0].idx;
1514 if (txinfo->band != IEEE80211_BAND_2GHZ)
1515 i += 4;
1516
1517 word = __carl9170_ratetable[i].hw_value & 0xf;
1518 if (i < 4)
1519 word |= ((skb->len + FCS_LEN) << (3 + 16)) + 0x0400;
1520 else
1521 word |= ((skb->len + FCS_LEN) << 16) + 0x0010;
1522
1523 carl9170_async_regwrite_begin(ar);
1524 carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP, word);
1525
1526 for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) {
1527 /*
1528 * XXX: This accesses beyond skb data for up
1529 * to the last 3 bytes!!
1530 */
1531
1532 if (old && (data[i] == old[i]))
1533 continue;
1534
1535 word = le32_to_cpu(data[i]);
1536 carl9170_async_regwrite(addr + 4 * i, word);
1537 }
1538 carl9170_async_regwrite_finish();
1539
1540 dev_kfree_skb_any(cvif->beacon);
1541 cvif->beacon = NULL;
1542
1543 err = carl9170_async_regwrite_result();
1544 if (!err)
1545 cvif->beacon = skb;
1546 spin_unlock_bh(&ar->beacon_lock);
1547 if (err)
1548 goto err_free;
1549
1550 if (submit) {
1551 err = carl9170_bcn_ctrl(ar, cvif->id,
1552 CARL9170_BCN_CTRL_CAB_TRIGGER,
1553 addr, skb->len + FCS_LEN);
1554
1555 if (err)
1556 goto err_free;
1557 }
1558out_unlock:
1559 rcu_read_unlock();
1560 return 0;
1561
1562err_unlock:
1563 spin_unlock_bh(&ar->beacon_lock);
1564
1565err_free:
1566 rcu_read_unlock();
1567 dev_kfree_skb_any(skb);
1568 return err;
1569}