diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2009-11-04 12:37:05 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-11-06 16:49:04 -0500 |
commit | 2ce33995216a088fc11e1f85768375580324174c (patch) | |
tree | acb2df03a8869ae2b28fb46666fb71b66ddacada | |
parent | fcf5154118849cca3cdf424e83f863225d8173e7 (diff) |
rt2800: add rt2800lib (part four)
Code unification.
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Acked-by: Ivo van Doorn <IvDoorn@gmail.com>
Acked-by: Gertjan van Wingerde <gwingerde@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800lib.c | 157 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800lib.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800pci.c | 157 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800usb.c | 158 |
4 files changed, 161 insertions, 313 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index ddd53c02be7a..5c7d74a6f16e 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
@@ -1658,3 +1658,160 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
1658 | return 0; | 1658 | return 0; |
1659 | } | 1659 | } |
1660 | EXPORT_SYMBOL_GPL(rt2800_init_rfcsr); | 1660 | EXPORT_SYMBOL_GPL(rt2800_init_rfcsr); |
1661 | |||
1662 | /* | ||
1663 | * IEEE80211 stack callback functions. | ||
1664 | */ | ||
1665 | static void rt2800_get_tkip_seq(struct ieee80211_hw *hw, u8 hw_key_idx, | ||
1666 | u32 *iv32, u16 *iv16) | ||
1667 | { | ||
1668 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
1669 | struct mac_iveiv_entry iveiv_entry; | ||
1670 | u32 offset; | ||
1671 | |||
1672 | offset = MAC_IVEIV_ENTRY(hw_key_idx); | ||
1673 | rt2800_register_multiread(rt2x00dev, offset, | ||
1674 | &iveiv_entry, sizeof(iveiv_entry)); | ||
1675 | |||
1676 | memcpy(&iveiv_entry.iv[0], iv16, sizeof(iv16)); | ||
1677 | memcpy(&iveiv_entry.iv[4], iv32, sizeof(iv32)); | ||
1678 | } | ||
1679 | |||
1680 | static int rt2800_set_rts_threshold(struct ieee80211_hw *hw, u32 value) | ||
1681 | { | ||
1682 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
1683 | u32 reg; | ||
1684 | bool enabled = (value < IEEE80211_MAX_RTS_THRESHOLD); | ||
1685 | |||
1686 | rt2800_register_read(rt2x00dev, TX_RTS_CFG, ®); | ||
1687 | rt2x00_set_field32(®, TX_RTS_CFG_RTS_THRES, value); | ||
1688 | rt2800_register_write(rt2x00dev, TX_RTS_CFG, reg); | ||
1689 | |||
1690 | rt2800_register_read(rt2x00dev, CCK_PROT_CFG, ®); | ||
1691 | rt2x00_set_field32(®, CCK_PROT_CFG_RTS_TH_EN, enabled); | ||
1692 | rt2800_register_write(rt2x00dev, CCK_PROT_CFG, reg); | ||
1693 | |||
1694 | rt2800_register_read(rt2x00dev, OFDM_PROT_CFG, ®); | ||
1695 | rt2x00_set_field32(®, OFDM_PROT_CFG_RTS_TH_EN, enabled); | ||
1696 | rt2800_register_write(rt2x00dev, OFDM_PROT_CFG, reg); | ||
1697 | |||
1698 | rt2800_register_read(rt2x00dev, MM20_PROT_CFG, ®); | ||
1699 | rt2x00_set_field32(®, MM20_PROT_CFG_RTS_TH_EN, enabled); | ||
1700 | rt2800_register_write(rt2x00dev, MM20_PROT_CFG, reg); | ||
1701 | |||
1702 | rt2800_register_read(rt2x00dev, MM40_PROT_CFG, ®); | ||
1703 | rt2x00_set_field32(®, MM40_PROT_CFG_RTS_TH_EN, enabled); | ||
1704 | rt2800_register_write(rt2x00dev, MM40_PROT_CFG, reg); | ||
1705 | |||
1706 | rt2800_register_read(rt2x00dev, GF20_PROT_CFG, ®); | ||
1707 | rt2x00_set_field32(®, GF20_PROT_CFG_RTS_TH_EN, enabled); | ||
1708 | rt2800_register_write(rt2x00dev, GF20_PROT_CFG, reg); | ||
1709 | |||
1710 | rt2800_register_read(rt2x00dev, GF40_PROT_CFG, ®); | ||
1711 | rt2x00_set_field32(®, GF40_PROT_CFG_RTS_TH_EN, enabled); | ||
1712 | rt2800_register_write(rt2x00dev, GF40_PROT_CFG, reg); | ||
1713 | |||
1714 | return 0; | ||
1715 | } | ||
1716 | |||
1717 | static int rt2800_conf_tx(struct ieee80211_hw *hw, u16 queue_idx, | ||
1718 | const struct ieee80211_tx_queue_params *params) | ||
1719 | { | ||
1720 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
1721 | struct data_queue *queue; | ||
1722 | struct rt2x00_field32 field; | ||
1723 | int retval; | ||
1724 | u32 reg; | ||
1725 | u32 offset; | ||
1726 | |||
1727 | /* | ||
1728 | * First pass the configuration through rt2x00lib, that will | ||
1729 | * update the queue settings and validate the input. After that | ||
1730 | * we are free to update the registers based on the value | ||
1731 | * in the queue parameter. | ||
1732 | */ | ||
1733 | retval = rt2x00mac_conf_tx(hw, queue_idx, params); | ||
1734 | if (retval) | ||
1735 | return retval; | ||
1736 | |||
1737 | /* | ||
1738 | * We only need to perform additional register initialization | ||
1739 | * for WMM queues/ | ||
1740 | */ | ||
1741 | if (queue_idx >= 4) | ||
1742 | return 0; | ||
1743 | |||
1744 | queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); | ||
1745 | |||
1746 | /* Update WMM TXOP register */ | ||
1747 | offset = WMM_TXOP0_CFG + (sizeof(u32) * (!!(queue_idx & 2))); | ||
1748 | field.bit_offset = (queue_idx & 1) * 16; | ||
1749 | field.bit_mask = 0xffff << field.bit_offset; | ||
1750 | |||
1751 | rt2800_register_read(rt2x00dev, offset, ®); | ||
1752 | rt2x00_set_field32(®, field, queue->txop); | ||
1753 | rt2800_register_write(rt2x00dev, offset, reg); | ||
1754 | |||
1755 | /* Update WMM registers */ | ||
1756 | field.bit_offset = queue_idx * 4; | ||
1757 | field.bit_mask = 0xf << field.bit_offset; | ||
1758 | |||
1759 | rt2800_register_read(rt2x00dev, WMM_AIFSN_CFG, ®); | ||
1760 | rt2x00_set_field32(®, field, queue->aifs); | ||
1761 | rt2800_register_write(rt2x00dev, WMM_AIFSN_CFG, reg); | ||
1762 | |||
1763 | rt2800_register_read(rt2x00dev, WMM_CWMIN_CFG, ®); | ||
1764 | rt2x00_set_field32(®, field, queue->cw_min); | ||
1765 | rt2800_register_write(rt2x00dev, WMM_CWMIN_CFG, reg); | ||
1766 | |||
1767 | rt2800_register_read(rt2x00dev, WMM_CWMAX_CFG, ®); | ||
1768 | rt2x00_set_field32(®, field, queue->cw_max); | ||
1769 | rt2800_register_write(rt2x00dev, WMM_CWMAX_CFG, reg); | ||
1770 | |||
1771 | /* Update EDCA registers */ | ||
1772 | offset = EDCA_AC0_CFG + (sizeof(u32) * queue_idx); | ||
1773 | |||
1774 | rt2800_register_read(rt2x00dev, offset, ®); | ||
1775 | rt2x00_set_field32(®, EDCA_AC0_CFG_TX_OP, queue->txop); | ||
1776 | rt2x00_set_field32(®, EDCA_AC0_CFG_AIFSN, queue->aifs); | ||
1777 | rt2x00_set_field32(®, EDCA_AC0_CFG_CWMIN, queue->cw_min); | ||
1778 | rt2x00_set_field32(®, EDCA_AC0_CFG_CWMAX, queue->cw_max); | ||
1779 | rt2800_register_write(rt2x00dev, offset, reg); | ||
1780 | |||
1781 | return 0; | ||
1782 | } | ||
1783 | |||
1784 | static u64 rt2800_get_tsf(struct ieee80211_hw *hw) | ||
1785 | { | ||
1786 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
1787 | u64 tsf; | ||
1788 | u32 reg; | ||
1789 | |||
1790 | rt2800_register_read(rt2x00dev, TSF_TIMER_DW1, ®); | ||
1791 | tsf = (u64) rt2x00_get_field32(reg, TSF_TIMER_DW1_HIGH_WORD) << 32; | ||
1792 | rt2800_register_read(rt2x00dev, TSF_TIMER_DW0, ®); | ||
1793 | tsf |= rt2x00_get_field32(reg, TSF_TIMER_DW0_LOW_WORD); | ||
1794 | |||
1795 | return tsf; | ||
1796 | } | ||
1797 | |||
1798 | const struct ieee80211_ops rt2800_mac80211_ops = { | ||
1799 | .tx = rt2x00mac_tx, | ||
1800 | .start = rt2x00mac_start, | ||
1801 | .stop = rt2x00mac_stop, | ||
1802 | .add_interface = rt2x00mac_add_interface, | ||
1803 | .remove_interface = rt2x00mac_remove_interface, | ||
1804 | .config = rt2x00mac_config, | ||
1805 | .configure_filter = rt2x00mac_configure_filter, | ||
1806 | .set_tim = rt2x00mac_set_tim, | ||
1807 | .set_key = rt2x00mac_set_key, | ||
1808 | .get_stats = rt2x00mac_get_stats, | ||
1809 | .get_tkip_seq = rt2800_get_tkip_seq, | ||
1810 | .set_rts_threshold = rt2800_set_rts_threshold, | ||
1811 | .bss_info_changed = rt2x00mac_bss_info_changed, | ||
1812 | .conf_tx = rt2800_conf_tx, | ||
1813 | .get_tx_stats = rt2x00mac_get_tx_stats, | ||
1814 | .get_tsf = rt2800_get_tsf, | ||
1815 | .rfkill_poll = rt2x00mac_rfkill_poll, | ||
1816 | }; | ||
1817 | EXPORT_SYMBOL_GPL(rt2800_mac80211_ops); | ||
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h index 2da8f79215fd..5eea8fcba6cc 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/rt2x00/rt2800lib.h | |||
@@ -129,4 +129,6 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev); | |||
129 | int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev); | 129 | int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev); |
130 | int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev); | 130 | int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev); |
131 | 131 | ||
132 | extern const struct ieee80211_ops rt2800_mac80211_ops; | ||
133 | |||
132 | #endif /* RT2800LIB_H */ | 134 | #endif /* RT2800LIB_H */ |
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 78086cce55ee..3c5b875cdee8 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c | |||
@@ -1513,161 +1513,6 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1513 | return 0; | 1513 | return 0; |
1514 | } | 1514 | } |
1515 | 1515 | ||
1516 | /* | ||
1517 | * IEEE80211 stack callback functions. | ||
1518 | */ | ||
1519 | static void rt2800pci_get_tkip_seq(struct ieee80211_hw *hw, u8 hw_key_idx, | ||
1520 | u32 *iv32, u16 *iv16) | ||
1521 | { | ||
1522 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
1523 | struct mac_iveiv_entry iveiv_entry; | ||
1524 | u32 offset; | ||
1525 | |||
1526 | offset = MAC_IVEIV_ENTRY(hw_key_idx); | ||
1527 | rt2800_register_multiread(rt2x00dev, offset, | ||
1528 | &iveiv_entry, sizeof(iveiv_entry)); | ||
1529 | |||
1530 | memcpy(&iveiv_entry.iv[0], iv16, sizeof(iv16)); | ||
1531 | memcpy(&iveiv_entry.iv[4], iv32, sizeof(iv32)); | ||
1532 | } | ||
1533 | |||
1534 | static int rt2800pci_set_rts_threshold(struct ieee80211_hw *hw, u32 value) | ||
1535 | { | ||
1536 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
1537 | u32 reg; | ||
1538 | bool enabled = (value < IEEE80211_MAX_RTS_THRESHOLD); | ||
1539 | |||
1540 | rt2800_register_read(rt2x00dev, TX_RTS_CFG, ®); | ||
1541 | rt2x00_set_field32(®, TX_RTS_CFG_RTS_THRES, value); | ||
1542 | rt2800_register_write(rt2x00dev, TX_RTS_CFG, reg); | ||
1543 | |||
1544 | rt2800_register_read(rt2x00dev, CCK_PROT_CFG, ®); | ||
1545 | rt2x00_set_field32(®, CCK_PROT_CFG_RTS_TH_EN, enabled); | ||
1546 | rt2800_register_write(rt2x00dev, CCK_PROT_CFG, reg); | ||
1547 | |||
1548 | rt2800_register_read(rt2x00dev, OFDM_PROT_CFG, ®); | ||
1549 | rt2x00_set_field32(®, OFDM_PROT_CFG_RTS_TH_EN, enabled); | ||
1550 | rt2800_register_write(rt2x00dev, OFDM_PROT_CFG, reg); | ||
1551 | |||
1552 | rt2800_register_read(rt2x00dev, MM20_PROT_CFG, ®); | ||
1553 | rt2x00_set_field32(®, MM20_PROT_CFG_RTS_TH_EN, enabled); | ||
1554 | rt2800_register_write(rt2x00dev, MM20_PROT_CFG, reg); | ||
1555 | |||
1556 | rt2800_register_read(rt2x00dev, MM40_PROT_CFG, ®); | ||
1557 | rt2x00_set_field32(®, MM40_PROT_CFG_RTS_TH_EN, enabled); | ||
1558 | rt2800_register_write(rt2x00dev, MM40_PROT_CFG, reg); | ||
1559 | |||
1560 | rt2800_register_read(rt2x00dev, GF20_PROT_CFG, ®); | ||
1561 | rt2x00_set_field32(®, GF20_PROT_CFG_RTS_TH_EN, enabled); | ||
1562 | rt2800_register_write(rt2x00dev, GF20_PROT_CFG, reg); | ||
1563 | |||
1564 | rt2800_register_read(rt2x00dev, GF40_PROT_CFG, ®); | ||
1565 | rt2x00_set_field32(®, GF40_PROT_CFG_RTS_TH_EN, enabled); | ||
1566 | rt2800_register_write(rt2x00dev, GF40_PROT_CFG, reg); | ||
1567 | |||
1568 | return 0; | ||
1569 | } | ||
1570 | |||
1571 | static int rt2800pci_conf_tx(struct ieee80211_hw *hw, u16 queue_idx, | ||
1572 | const struct ieee80211_tx_queue_params *params) | ||
1573 | { | ||
1574 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
1575 | struct data_queue *queue; | ||
1576 | struct rt2x00_field32 field; | ||
1577 | int retval; | ||
1578 | u32 reg; | ||
1579 | u32 offset; | ||
1580 | |||
1581 | /* | ||
1582 | * First pass the configuration through rt2x00lib, that will | ||
1583 | * update the queue settings and validate the input. After that | ||
1584 | * we are free to update the registers based on the value | ||
1585 | * in the queue parameter. | ||
1586 | */ | ||
1587 | retval = rt2x00mac_conf_tx(hw, queue_idx, params); | ||
1588 | if (retval) | ||
1589 | return retval; | ||
1590 | |||
1591 | /* | ||
1592 | * We only need to perform additional register initialization | ||
1593 | * for WMM queues/ | ||
1594 | */ | ||
1595 | if (queue_idx >= 4) | ||
1596 | return 0; | ||
1597 | |||
1598 | queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); | ||
1599 | |||
1600 | /* Update WMM TXOP register */ | ||
1601 | offset = WMM_TXOP0_CFG + (sizeof(u32) * (!!(queue_idx & 2))); | ||
1602 | field.bit_offset = (queue_idx & 1) * 16; | ||
1603 | field.bit_mask = 0xffff << field.bit_offset; | ||
1604 | |||
1605 | rt2800_register_read(rt2x00dev, offset, ®); | ||
1606 | rt2x00_set_field32(®, field, queue->txop); | ||
1607 | rt2800_register_write(rt2x00dev, offset, reg); | ||
1608 | |||
1609 | /* Update WMM registers */ | ||
1610 | field.bit_offset = queue_idx * 4; | ||
1611 | field.bit_mask = 0xf << field.bit_offset; | ||
1612 | |||
1613 | rt2800_register_read(rt2x00dev, WMM_AIFSN_CFG, ®); | ||
1614 | rt2x00_set_field32(®, field, queue->aifs); | ||
1615 | rt2800_register_write(rt2x00dev, WMM_AIFSN_CFG, reg); | ||
1616 | |||
1617 | rt2800_register_read(rt2x00dev, WMM_CWMIN_CFG, ®); | ||
1618 | rt2x00_set_field32(®, field, queue->cw_min); | ||
1619 | rt2800_register_write(rt2x00dev, WMM_CWMIN_CFG, reg); | ||
1620 | |||
1621 | rt2800_register_read(rt2x00dev, WMM_CWMAX_CFG, ®); | ||
1622 | rt2x00_set_field32(®, field, queue->cw_max); | ||
1623 | rt2800_register_write(rt2x00dev, WMM_CWMAX_CFG, reg); | ||
1624 | |||
1625 | /* Update EDCA registers */ | ||
1626 | offset = EDCA_AC0_CFG + (sizeof(u32) * queue_idx); | ||
1627 | |||
1628 | rt2800_register_read(rt2x00dev, offset, ®); | ||
1629 | rt2x00_set_field32(®, EDCA_AC0_CFG_TX_OP, queue->txop); | ||
1630 | rt2x00_set_field32(®, EDCA_AC0_CFG_AIFSN, queue->aifs); | ||
1631 | rt2x00_set_field32(®, EDCA_AC0_CFG_CWMIN, queue->cw_min); | ||
1632 | rt2x00_set_field32(®, EDCA_AC0_CFG_CWMAX, queue->cw_max); | ||
1633 | rt2800_register_write(rt2x00dev, offset, reg); | ||
1634 | |||
1635 | return 0; | ||
1636 | } | ||
1637 | |||
1638 | static u64 rt2800pci_get_tsf(struct ieee80211_hw *hw) | ||
1639 | { | ||
1640 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
1641 | u64 tsf; | ||
1642 | u32 reg; | ||
1643 | |||
1644 | rt2800_register_read(rt2x00dev, TSF_TIMER_DW1, ®); | ||
1645 | tsf = (u64) rt2x00_get_field32(reg, TSF_TIMER_DW1_HIGH_WORD) << 32; | ||
1646 | rt2800_register_read(rt2x00dev, TSF_TIMER_DW0, ®); | ||
1647 | tsf |= rt2x00_get_field32(reg, TSF_TIMER_DW0_LOW_WORD); | ||
1648 | |||
1649 | return tsf; | ||
1650 | } | ||
1651 | |||
1652 | static const struct ieee80211_ops rt2800pci_mac80211_ops = { | ||
1653 | .tx = rt2x00mac_tx, | ||
1654 | .start = rt2x00mac_start, | ||
1655 | .stop = rt2x00mac_stop, | ||
1656 | .add_interface = rt2x00mac_add_interface, | ||
1657 | .remove_interface = rt2x00mac_remove_interface, | ||
1658 | .config = rt2x00mac_config, | ||
1659 | .configure_filter = rt2x00mac_configure_filter, | ||
1660 | .set_key = rt2x00mac_set_key, | ||
1661 | .get_stats = rt2x00mac_get_stats, | ||
1662 | .get_tkip_seq = rt2800pci_get_tkip_seq, | ||
1663 | .set_rts_threshold = rt2800pci_set_rts_threshold, | ||
1664 | .bss_info_changed = rt2x00mac_bss_info_changed, | ||
1665 | .conf_tx = rt2800pci_conf_tx, | ||
1666 | .get_tx_stats = rt2x00mac_get_tx_stats, | ||
1667 | .get_tsf = rt2800pci_get_tsf, | ||
1668 | .rfkill_poll = rt2x00mac_rfkill_poll, | ||
1669 | }; | ||
1670 | |||
1671 | static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { | 1516 | static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { |
1672 | .irq_handler = rt2800pci_interrupt, | 1517 | .irq_handler = rt2800pci_interrupt, |
1673 | .probe_hw = rt2800pci_probe_hw, | 1518 | .probe_hw = rt2800pci_probe_hw, |
@@ -1730,7 +1575,7 @@ static const struct rt2x00_ops rt2800pci_ops = { | |||
1730 | .tx = &rt2800pci_queue_tx, | 1575 | .tx = &rt2800pci_queue_tx, |
1731 | .bcn = &rt2800pci_queue_bcn, | 1576 | .bcn = &rt2800pci_queue_bcn, |
1732 | .lib = &rt2800pci_rt2x00_ops, | 1577 | .lib = &rt2800pci_rt2x00_ops, |
1733 | .hw = &rt2800pci_mac80211_ops, | 1578 | .hw = &rt2800_mac80211_ops, |
1734 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 1579 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS |
1735 | .debugfs = &rt2800_rt2x00debug, | 1580 | .debugfs = &rt2800_rt2x00debug, |
1736 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | 1581 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ |
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index f5b864b1a55d..ce2e893856c1 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
@@ -1119,162 +1119,6 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1119 | return 0; | 1119 | return 0; |
1120 | } | 1120 | } |
1121 | 1121 | ||
1122 | /* | ||
1123 | * IEEE80211 stack callback functions. | ||
1124 | */ | ||
1125 | static void rt2800usb_get_tkip_seq(struct ieee80211_hw *hw, u8 hw_key_idx, | ||
1126 | u32 *iv32, u16 *iv16) | ||
1127 | { | ||
1128 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
1129 | struct mac_iveiv_entry iveiv_entry; | ||
1130 | u32 offset; | ||
1131 | |||
1132 | offset = MAC_IVEIV_ENTRY(hw_key_idx); | ||
1133 | rt2800_register_multiread(rt2x00dev, offset, | ||
1134 | &iveiv_entry, sizeof(iveiv_entry)); | ||
1135 | |||
1136 | memcpy(&iveiv_entry.iv[0], iv16, sizeof(iv16)); | ||
1137 | memcpy(&iveiv_entry.iv[4], iv32, sizeof(iv32)); | ||
1138 | } | ||
1139 | |||
1140 | static int rt2800usb_set_rts_threshold(struct ieee80211_hw *hw, u32 value) | ||
1141 | { | ||
1142 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
1143 | u32 reg; | ||
1144 | bool enabled = (value < IEEE80211_MAX_RTS_THRESHOLD); | ||
1145 | |||
1146 | rt2800_register_read(rt2x00dev, TX_RTS_CFG, ®); | ||
1147 | rt2x00_set_field32(®, TX_RTS_CFG_RTS_THRES, value); | ||
1148 | rt2800_register_write(rt2x00dev, TX_RTS_CFG, reg); | ||
1149 | |||
1150 | rt2800_register_read(rt2x00dev, CCK_PROT_CFG, ®); | ||
1151 | rt2x00_set_field32(®, CCK_PROT_CFG_RTS_TH_EN, enabled); | ||
1152 | rt2800_register_write(rt2x00dev, CCK_PROT_CFG, reg); | ||
1153 | |||
1154 | rt2800_register_read(rt2x00dev, OFDM_PROT_CFG, ®); | ||
1155 | rt2x00_set_field32(®, OFDM_PROT_CFG_RTS_TH_EN, enabled); | ||
1156 | rt2800_register_write(rt2x00dev, OFDM_PROT_CFG, reg); | ||
1157 | |||
1158 | rt2800_register_read(rt2x00dev, MM20_PROT_CFG, ®); | ||
1159 | rt2x00_set_field32(®, MM20_PROT_CFG_RTS_TH_EN, enabled); | ||
1160 | rt2800_register_write(rt2x00dev, MM20_PROT_CFG, reg); | ||
1161 | |||
1162 | rt2800_register_read(rt2x00dev, MM40_PROT_CFG, ®); | ||
1163 | rt2x00_set_field32(®, MM40_PROT_CFG_RTS_TH_EN, enabled); | ||
1164 | rt2800_register_write(rt2x00dev, MM40_PROT_CFG, reg); | ||
1165 | |||
1166 | rt2800_register_read(rt2x00dev, GF20_PROT_CFG, ®); | ||
1167 | rt2x00_set_field32(®, GF20_PROT_CFG_RTS_TH_EN, enabled); | ||
1168 | rt2800_register_write(rt2x00dev, GF20_PROT_CFG, reg); | ||
1169 | |||
1170 | rt2800_register_read(rt2x00dev, GF40_PROT_CFG, ®); | ||
1171 | rt2x00_set_field32(®, GF40_PROT_CFG_RTS_TH_EN, enabled); | ||
1172 | rt2800_register_write(rt2x00dev, GF40_PROT_CFG, reg); | ||
1173 | |||
1174 | return 0; | ||
1175 | } | ||
1176 | |||
1177 | static int rt2800usb_conf_tx(struct ieee80211_hw *hw, u16 queue_idx, | ||
1178 | const struct ieee80211_tx_queue_params *params) | ||
1179 | { | ||
1180 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
1181 | struct data_queue *queue; | ||
1182 | struct rt2x00_field32 field; | ||
1183 | int retval; | ||
1184 | u32 reg; | ||
1185 | u32 offset; | ||
1186 | |||
1187 | /* | ||
1188 | * First pass the configuration through rt2x00lib, that will | ||
1189 | * update the queue settings and validate the input. After that | ||
1190 | * we are free to update the registers based on the value | ||
1191 | * in the queue parameter. | ||
1192 | */ | ||
1193 | retval = rt2x00mac_conf_tx(hw, queue_idx, params); | ||
1194 | if (retval) | ||
1195 | return retval; | ||
1196 | |||
1197 | /* | ||
1198 | * We only need to perform additional register initialization | ||
1199 | * for WMM queues/ | ||
1200 | */ | ||
1201 | if (queue_idx >= 4) | ||
1202 | return 0; | ||
1203 | |||
1204 | queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); | ||
1205 | |||
1206 | /* Update WMM TXOP register */ | ||
1207 | offset = WMM_TXOP0_CFG + (sizeof(u32) * (!!(queue_idx & 2))); | ||
1208 | field.bit_offset = (queue_idx & 1) * 16; | ||
1209 | field.bit_mask = 0xffff << field.bit_offset; | ||
1210 | |||
1211 | rt2800_register_read(rt2x00dev, offset, ®); | ||
1212 | rt2x00_set_field32(®, field, queue->txop); | ||
1213 | rt2800_register_write(rt2x00dev, offset, reg); | ||
1214 | |||
1215 | /* Update WMM registers */ | ||
1216 | field.bit_offset = queue_idx * 4; | ||
1217 | field.bit_mask = 0xf << field.bit_offset; | ||
1218 | |||
1219 | rt2800_register_read(rt2x00dev, WMM_AIFSN_CFG, ®); | ||
1220 | rt2x00_set_field32(®, field, queue->aifs); | ||
1221 | rt2800_register_write(rt2x00dev, WMM_AIFSN_CFG, reg); | ||
1222 | |||
1223 | rt2800_register_read(rt2x00dev, WMM_CWMIN_CFG, ®); | ||
1224 | rt2x00_set_field32(®, field, queue->cw_min); | ||
1225 | rt2800_register_write(rt2x00dev, WMM_CWMIN_CFG, reg); | ||
1226 | |||
1227 | rt2800_register_read(rt2x00dev, WMM_CWMAX_CFG, ®); | ||
1228 | rt2x00_set_field32(®, field, queue->cw_max); | ||
1229 | rt2800_register_write(rt2x00dev, WMM_CWMAX_CFG, reg); | ||
1230 | |||
1231 | /* Update EDCA registers */ | ||
1232 | offset = EDCA_AC0_CFG + (sizeof(u32) * queue_idx); | ||
1233 | |||
1234 | rt2800_register_read(rt2x00dev, offset, ®); | ||
1235 | rt2x00_set_field32(®, EDCA_AC0_CFG_TX_OP, queue->txop); | ||
1236 | rt2x00_set_field32(®, EDCA_AC0_CFG_AIFSN, queue->aifs); | ||
1237 | rt2x00_set_field32(®, EDCA_AC0_CFG_CWMIN, queue->cw_min); | ||
1238 | rt2x00_set_field32(®, EDCA_AC0_CFG_CWMAX, queue->cw_max); | ||
1239 | rt2800_register_write(rt2x00dev, offset, reg); | ||
1240 | |||
1241 | return 0; | ||
1242 | } | ||
1243 | |||
1244 | static u64 rt2800usb_get_tsf(struct ieee80211_hw *hw) | ||
1245 | { | ||
1246 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
1247 | u64 tsf; | ||
1248 | u32 reg; | ||
1249 | |||
1250 | rt2800_register_read(rt2x00dev, TSF_TIMER_DW1, ®); | ||
1251 | tsf = (u64) rt2x00_get_field32(reg, TSF_TIMER_DW1_HIGH_WORD) << 32; | ||
1252 | rt2800_register_read(rt2x00dev, TSF_TIMER_DW0, ®); | ||
1253 | tsf |= rt2x00_get_field32(reg, TSF_TIMER_DW0_LOW_WORD); | ||
1254 | |||
1255 | return tsf; | ||
1256 | } | ||
1257 | |||
1258 | static const struct ieee80211_ops rt2800usb_mac80211_ops = { | ||
1259 | .tx = rt2x00mac_tx, | ||
1260 | .start = rt2x00mac_start, | ||
1261 | .stop = rt2x00mac_stop, | ||
1262 | .add_interface = rt2x00mac_add_interface, | ||
1263 | .remove_interface = rt2x00mac_remove_interface, | ||
1264 | .config = rt2x00mac_config, | ||
1265 | .configure_filter = rt2x00mac_configure_filter, | ||
1266 | .set_tim = rt2x00mac_set_tim, | ||
1267 | .set_key = rt2x00mac_set_key, | ||
1268 | .get_stats = rt2x00mac_get_stats, | ||
1269 | .get_tkip_seq = rt2800usb_get_tkip_seq, | ||
1270 | .set_rts_threshold = rt2800usb_set_rts_threshold, | ||
1271 | .bss_info_changed = rt2x00mac_bss_info_changed, | ||
1272 | .conf_tx = rt2800usb_conf_tx, | ||
1273 | .get_tx_stats = rt2x00mac_get_tx_stats, | ||
1274 | .get_tsf = rt2800usb_get_tsf, | ||
1275 | .rfkill_poll = rt2x00mac_rfkill_poll, | ||
1276 | }; | ||
1277 | |||
1278 | static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { | 1122 | static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { |
1279 | .probe_hw = rt2800usb_probe_hw, | 1123 | .probe_hw = rt2800usb_probe_hw, |
1280 | .get_firmware_name = rt2800usb_get_firmware_name, | 1124 | .get_firmware_name = rt2800usb_get_firmware_name, |
@@ -1336,7 +1180,7 @@ static const struct rt2x00_ops rt2800usb_ops = { | |||
1336 | .tx = &rt2800usb_queue_tx, | 1180 | .tx = &rt2800usb_queue_tx, |
1337 | .bcn = &rt2800usb_queue_bcn, | 1181 | .bcn = &rt2800usb_queue_bcn, |
1338 | .lib = &rt2800usb_rt2x00_ops, | 1182 | .lib = &rt2800usb_rt2x00_ops, |
1339 | .hw = &rt2800usb_mac80211_ops, | 1183 | .hw = &rt2800_mac80211_ops, |
1340 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 1184 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS |
1341 | .debugfs = &rt2800_rt2x00debug, | 1185 | .debugfs = &rt2800_rt2x00debug, |
1342 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | 1186 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ |