aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/carl9170/main.c
diff options
context:
space:
mode:
authorChristian Lamparter <chunkeey@googlemail.com>2011-08-15 14:09:54 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-08-24 14:41:42 -0400
commit00044f17afd36bf6397b9a2a12f242a057449e9a (patch)
tree5b216a3fa13357b352bebd28272e0698380a2b54 /drivers/net/wireless/ath/carl9170/main.c
parentacf1771221f2877ab5d36487930cd6a2ecaa73e6 (diff)
carl9170: export HW random number generator
All AR9170 hardware have a 16-Bit random number generator. The documentation claims the values are suitable for "security keys". The "throughput" is around 320Kibit/s. It's slow, but it does work without introducing any special offload firmware commands. Signed-off-by: Christian Lamparter <chunkeey@googlemail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/carl9170/main.c')
-rw-r--r--drivers/net/wireless/ath/carl9170/main.c113
1 files changed, 113 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c
index 85cb1bdebaaa..782b8f3ae58f 100644
--- a/drivers/net/wireless/ath/carl9170/main.c
+++ b/drivers/net/wireless/ath/carl9170/main.c
@@ -1468,6 +1468,109 @@ static int carl9170_register_wps_button(struct ar9170 *ar)
1468} 1468}
1469#endif /* CONFIG_CARL9170_WPC */ 1469#endif /* CONFIG_CARL9170_WPC */
1470 1470
1471#ifdef CONFIG_CARL9170_HWRNG
1472static int carl9170_rng_get(struct ar9170 *ar)
1473{
1474
1475#define RW (CARL9170_MAX_CMD_PAYLOAD_LEN / sizeof(u32))
1476#define RB (CARL9170_MAX_CMD_PAYLOAD_LEN)
1477
1478 static const __le32 rng_load[RW] = {
1479 [0 ... (RW - 1)] = cpu_to_le32(AR9170_RAND_REG_NUM)};
1480
1481 u32 buf[RW];
1482
1483 unsigned int i, off = 0, transfer, count;
1484 int err;
1485
1486 BUILD_BUG_ON(RB > CARL9170_MAX_CMD_PAYLOAD_LEN);
1487
1488 if (!IS_ACCEPTING_CMD(ar) || !ar->rng.initialized)
1489 return -EAGAIN;
1490
1491 count = ARRAY_SIZE(ar->rng.cache);
1492 while (count) {
1493 err = carl9170_exec_cmd(ar, CARL9170_CMD_RREG,
1494 RB, (u8 *) rng_load,
1495 RB, (u8 *) buf);
1496 if (err)
1497 return err;
1498
1499 transfer = min_t(unsigned int, count, RW);
1500 for (i = 0; i < transfer; i++)
1501 ar->rng.cache[off + i] = buf[i];
1502
1503 off += transfer;
1504 count -= transfer;
1505 }
1506
1507 ar->rng.cache_idx = 0;
1508
1509#undef RW
1510#undef RB
1511 return 0;
1512}
1513
1514static int carl9170_rng_read(struct hwrng *rng, u32 *data)
1515{
1516 struct ar9170 *ar = (struct ar9170 *)rng->priv;
1517 int ret = -EIO;
1518
1519 mutex_lock(&ar->mutex);
1520 if (ar->rng.cache_idx >= ARRAY_SIZE(ar->rng.cache)) {
1521 ret = carl9170_rng_get(ar);
1522 if (ret) {
1523 mutex_unlock(&ar->mutex);
1524 return ret;
1525 }
1526 }
1527
1528 *data = ar->rng.cache[ar->rng.cache_idx++];
1529 mutex_unlock(&ar->mutex);
1530
1531 return sizeof(u16);
1532}
1533
1534static void carl9170_unregister_hwrng(struct ar9170 *ar)
1535{
1536 if (ar->rng.initialized) {
1537 hwrng_unregister(&ar->rng.rng);
1538 ar->rng.initialized = false;
1539 }
1540}
1541
1542static int carl9170_register_hwrng(struct ar9170 *ar)
1543{
1544 int err;
1545
1546 snprintf(ar->rng.name, ARRAY_SIZE(ar->rng.name),
1547 "%s_%s", KBUILD_MODNAME, wiphy_name(ar->hw->wiphy));
1548 ar->rng.rng.name = ar->rng.name;
1549 ar->rng.rng.data_read = carl9170_rng_read;
1550 ar->rng.rng.priv = (unsigned long)ar;
1551
1552 if (WARN_ON(ar->rng.initialized))
1553 return -EALREADY;
1554
1555 err = hwrng_register(&ar->rng.rng);
1556 if (err) {
1557 dev_err(&ar->udev->dev, "Failed to register the random "
1558 "number generator (%d)\n", err);
1559 return err;
1560 }
1561
1562 ar->rng.initialized = true;
1563
1564 err = carl9170_rng_get(ar);
1565 if (err) {
1566 carl9170_unregister_hwrng(ar);
1567 return err;
1568 }
1569
1570 return 0;
1571}
1572#endif /* CONFIG_CARL9170_HWRNG */
1573
1471static int carl9170_op_get_survey(struct ieee80211_hw *hw, int idx, 1574static int carl9170_op_get_survey(struct ieee80211_hw *hw, int idx,
1472 struct survey_info *survey) 1575 struct survey_info *survey)
1473{ 1576{
@@ -1878,6 +1981,12 @@ int carl9170_register(struct ar9170 *ar)
1878 goto err_unreg; 1981 goto err_unreg;
1879#endif /* CONFIG_CARL9170_WPC */ 1982#endif /* CONFIG_CARL9170_WPC */
1880 1983
1984#ifdef CONFIG_CARL9170_HWRNG
1985 err = carl9170_register_hwrng(ar);
1986 if (err)
1987 goto err_unreg;
1988#endif /* CONFIG_CARL9170_HWRNG */
1989
1881 dev_info(&ar->udev->dev, "Atheros AR9170 is registered as '%s'\n", 1990 dev_info(&ar->udev->dev, "Atheros AR9170 is registered as '%s'\n",
1882 wiphy_name(ar->hw->wiphy)); 1991 wiphy_name(ar->hw->wiphy));
1883 1992
@@ -1910,6 +2019,10 @@ void carl9170_unregister(struct ar9170 *ar)
1910 } 2019 }
1911#endif /* CONFIG_CARL9170_WPC */ 2020#endif /* CONFIG_CARL9170_WPC */
1912 2021
2022#ifdef CONFIG_CARL9170_HWRNG
2023 carl9170_unregister_hwrng(ar);
2024#endif /* CONFIG_CARL9170_HWRNG */
2025
1913 carl9170_cancel_worker(ar); 2026 carl9170_cancel_worker(ar);
1914 cancel_work_sync(&ar->restart_work); 2027 cancel_work_sync(&ar->restart_work);
1915 2028