diff options
author | Christian Lamparter <chunkeey@googlemail.com> | 2011-07-16 11:25:14 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-07-18 14:29:43 -0400 |
commit | 943c33996f9b0851c4122dc96cae08d4ba8debf0 (patch) | |
tree | 679bc1439f9c9e0867f4abc19ed0899ca792fab2 | |
parent | 43b52a5ae9b56c02fbf6e2d7de3c50ebf9ff7973 (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.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/carl9170/mac.c | 129 | ||||
-rw-r--r-- | drivers/net/wireless/ath/carl9170/tx.c | 129 |
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); | |||
532 | int carl9170_set_slot_time(struct ar9170 *ar); | 532 | int carl9170_set_slot_time(struct ar9170 *ar); |
533 | int carl9170_set_mac_rates(struct ar9170 *ar); | 533 | int carl9170_set_mac_rates(struct ar9170 *ar); |
534 | int carl9170_set_hwretry_limit(struct ar9170 *ar, const u32 max_retry); | 534 | int carl9170_set_hwretry_limit(struct ar9170 *ar, const u32 max_retry); |
535 | int carl9170_update_beacon(struct ar9170 *ar, const bool submit); | ||
536 | int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac, | 535 | int 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); |
538 | int carl9170_disable_key(struct ar9170 *ar, const u8 id); | 537 | int carl9170_disable_key(struct ar9170 *ar, const u8 id); |
@@ -553,6 +552,7 @@ void carl9170_tx_drop(struct ar9170 *ar, struct sk_buff *skb); | |||
553 | void carl9170_tx_scheduler(struct ar9170 *ar); | 552 | void carl9170_tx_scheduler(struct ar9170 *ar); |
554 | void carl9170_tx_get_skb(struct sk_buff *skb); | 553 | void carl9170_tx_get_skb(struct sk_buff *skb); |
555 | int carl9170_tx_put_skb(struct sk_buff *skb); | 554 | int carl9170_tx_put_skb(struct sk_buff *skb); |
555 | int 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 | ||
458 | int 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); | ||
469 | retry: | ||
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 | |||
483 | found: | ||
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 | } | ||
574 | out_unlock: | ||
575 | rcu_read_unlock(); | ||
576 | return 0; | ||
577 | |||
578 | err_unlock: | ||
579 | spin_unlock_bh(&ar->beacon_lock); | ||
580 | |||
581 | err_free: | ||
582 | rcu_read_unlock(); | ||
583 | dev_kfree_skb_any(skb); | ||
584 | return err; | ||
585 | } | ||
586 | |||
587 | int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac, | 458 | int 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 | |||
1442 | int 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); | ||
1453 | retry: | ||
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 | |||
1467 | found: | ||
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 | } | ||
1558 | out_unlock: | ||
1559 | rcu_read_unlock(); | ||
1560 | return 0; | ||
1561 | |||
1562 | err_unlock: | ||
1563 | spin_unlock_bh(&ar->beacon_lock); | ||
1564 | |||
1565 | err_free: | ||
1566 | rcu_read_unlock(); | ||
1567 | dev_kfree_skb_any(skb); | ||
1568 | return err; | ||
1569 | } | ||