diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2500usb.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500usb.c | 154 |
1 files changed, 60 insertions, 94 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 8ce1726d7508..1423fd0bdbb3 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -1100,6 +1100,65 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1100 | rt2x00_desc_write(txd, 0, word); | 1100 | rt2x00_desc_write(txd, 0, word); |
1101 | } | 1101 | } |
1102 | 1102 | ||
1103 | /* | ||
1104 | * TX data initialization | ||
1105 | */ | ||
1106 | static void rt2500usb_beacondone(struct urb *urb); | ||
1107 | |||
1108 | static void rt2500usb_write_beacon(struct queue_entry *entry) | ||
1109 | { | ||
1110 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
1111 | struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); | ||
1112 | struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data; | ||
1113 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | ||
1114 | int pipe = usb_sndbulkpipe(usb_dev, 1); | ||
1115 | int length; | ||
1116 | u16 reg; | ||
1117 | |||
1118 | /* | ||
1119 | * Add the descriptor in front of the skb. | ||
1120 | */ | ||
1121 | skb_push(entry->skb, entry->queue->desc_size); | ||
1122 | memcpy(entry->skb->data, skbdesc->desc, skbdesc->desc_len); | ||
1123 | skbdesc->desc = entry->skb->data; | ||
1124 | |||
1125 | /* | ||
1126 | * Disable beaconing while we are reloading the beacon data, | ||
1127 | * otherwise we might be sending out invalid data. | ||
1128 | */ | ||
1129 | rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); | ||
1130 | rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 0); | ||
1131 | rt2x00_set_field16(®, TXRX_CSR19_TBCN, 0); | ||
1132 | rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 0); | ||
1133 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); | ||
1134 | |||
1135 | /* | ||
1136 | * USB devices cannot blindly pass the skb->len as the | ||
1137 | * length of the data to usb_fill_bulk_urb. Pass the skb | ||
1138 | * to the driver to determine what the length should be. | ||
1139 | */ | ||
1140 | length = rt2x00dev->ops->lib->get_tx_data_len(rt2x00dev, entry->skb); | ||
1141 | |||
1142 | usb_fill_bulk_urb(bcn_priv->urb, usb_dev, pipe, | ||
1143 | entry->skb->data, length, rt2500usb_beacondone, | ||
1144 | entry); | ||
1145 | |||
1146 | /* | ||
1147 | * Second we need to create the guardian byte. | ||
1148 | * We only need a single byte, so lets recycle | ||
1149 | * the 'flags' field we are not using for beacons. | ||
1150 | */ | ||
1151 | bcn_priv->guardian_data = 0; | ||
1152 | usb_fill_bulk_urb(bcn_priv->guardian_urb, usb_dev, pipe, | ||
1153 | &bcn_priv->guardian_data, 1, rt2500usb_beacondone, | ||
1154 | entry); | ||
1155 | |||
1156 | /* | ||
1157 | * Send out the guardian byte. | ||
1158 | */ | ||
1159 | usb_submit_urb(bcn_priv->guardian_urb, GFP_ATOMIC); | ||
1160 | } | ||
1161 | |||
1103 | static int rt2500usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev, | 1162 | static int rt2500usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev, |
1104 | struct sk_buff *skb) | 1163 | struct sk_buff *skb) |
1105 | { | 1164 | { |
@@ -1115,9 +1174,6 @@ static int rt2500usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev, | |||
1115 | return length; | 1174 | return length; |
1116 | } | 1175 | } |
1117 | 1176 | ||
1118 | /* | ||
1119 | * TX data initialization | ||
1120 | */ | ||
1121 | static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1177 | static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1122 | const enum data_queue_qid queue) | 1178 | const enum data_queue_qid queue) |
1123 | { | 1179 | { |
@@ -1672,96 +1728,6 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1672 | return 0; | 1728 | return 0; |
1673 | } | 1729 | } |
1674 | 1730 | ||
1675 | /* | ||
1676 | * IEEE80211 stack callback functions. | ||
1677 | */ | ||
1678 | static int rt2500usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
1679 | { | ||
1680 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
1681 | struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); | ||
1682 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
1683 | struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); | ||
1684 | struct queue_entry_priv_usb_bcn *bcn_priv; | ||
1685 | struct skb_frame_desc *skbdesc; | ||
1686 | struct txentry_desc txdesc; | ||
1687 | int pipe = usb_sndbulkpipe(usb_dev, 1); | ||
1688 | int length; | ||
1689 | u16 reg; | ||
1690 | |||
1691 | if (unlikely(!intf->beacon)) | ||
1692 | return -ENOBUFS; | ||
1693 | |||
1694 | bcn_priv = intf->beacon->priv_data; | ||
1695 | |||
1696 | /* | ||
1697 | * Copy all TX descriptor information into txdesc, | ||
1698 | * after that we are free to use the skb->cb array | ||
1699 | * for our information. | ||
1700 | */ | ||
1701 | intf->beacon->skb = skb; | ||
1702 | rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc); | ||
1703 | |||
1704 | /* | ||
1705 | * Add the descriptor in front of the skb. | ||
1706 | */ | ||
1707 | skb_push(skb, intf->beacon->queue->desc_size); | ||
1708 | memset(skb->data, 0, intf->beacon->queue->desc_size); | ||
1709 | |||
1710 | /* | ||
1711 | * Fill in skb descriptor | ||
1712 | */ | ||
1713 | skbdesc = get_skb_frame_desc(skb); | ||
1714 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
1715 | skbdesc->desc = skb->data; | ||
1716 | skbdesc->desc_len = intf->beacon->queue->desc_size; | ||
1717 | skbdesc->entry = intf->beacon; | ||
1718 | |||
1719 | /* | ||
1720 | * Disable beaconing while we are reloading the beacon data, | ||
1721 | * otherwise we might be sending out invalid data. | ||
1722 | */ | ||
1723 | rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); | ||
1724 | rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 0); | ||
1725 | rt2x00_set_field16(®, TXRX_CSR19_TBCN, 0); | ||
1726 | rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 0); | ||
1727 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); | ||
1728 | |||
1729 | rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc); | ||
1730 | |||
1731 | /* | ||
1732 | * USB devices cannot blindly pass the skb->len as the | ||
1733 | * length of the data to usb_fill_bulk_urb. Pass the skb | ||
1734 | * to the driver to determine what the length should be. | ||
1735 | */ | ||
1736 | length = rt2500usb_get_tx_data_len(rt2x00dev, skb); | ||
1737 | |||
1738 | usb_fill_bulk_urb(bcn_priv->urb, usb_dev, pipe, | ||
1739 | skb->data, length, rt2500usb_beacondone, | ||
1740 | intf->beacon); | ||
1741 | |||
1742 | /* | ||
1743 | * Second we need to create the guardian byte. | ||
1744 | * We only need a single byte, so lets recycle | ||
1745 | * the 'flags' field we are not using for beacons. | ||
1746 | */ | ||
1747 | bcn_priv->guardian_data = 0; | ||
1748 | usb_fill_bulk_urb(bcn_priv->guardian_urb, usb_dev, pipe, | ||
1749 | &bcn_priv->guardian_data, 1, rt2500usb_beacondone, | ||
1750 | intf->beacon); | ||
1751 | |||
1752 | /* | ||
1753 | * Send out the guardian byte. | ||
1754 | */ | ||
1755 | usb_submit_urb(bcn_priv->guardian_urb, GFP_ATOMIC); | ||
1756 | |||
1757 | /* | ||
1758 | * Enable beacon generation. | ||
1759 | */ | ||
1760 | rt2500usb_kick_tx_queue(rt2x00dev, QID_BEACON); | ||
1761 | |||
1762 | return 0; | ||
1763 | } | ||
1764 | |||
1765 | static const struct ieee80211_ops rt2500usb_mac80211_ops = { | 1731 | static const struct ieee80211_ops rt2500usb_mac80211_ops = { |
1766 | .tx = rt2x00mac_tx, | 1732 | .tx = rt2x00mac_tx, |
1767 | .start = rt2x00mac_start, | 1733 | .start = rt2x00mac_start, |
@@ -1789,10 +1755,10 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { | |||
1789 | .link_tuner = rt2500usb_link_tuner, | 1755 | .link_tuner = rt2500usb_link_tuner, |
1790 | .write_tx_desc = rt2500usb_write_tx_desc, | 1756 | .write_tx_desc = rt2500usb_write_tx_desc, |
1791 | .write_tx_data = rt2x00usb_write_tx_data, | 1757 | .write_tx_data = rt2x00usb_write_tx_data, |
1758 | .write_beacon = rt2500usb_write_beacon, | ||
1792 | .get_tx_data_len = rt2500usb_get_tx_data_len, | 1759 | .get_tx_data_len = rt2500usb_get_tx_data_len, |
1793 | .kick_tx_queue = rt2500usb_kick_tx_queue, | 1760 | .kick_tx_queue = rt2500usb_kick_tx_queue, |
1794 | .fill_rxdone = rt2500usb_fill_rxdone, | 1761 | .fill_rxdone = rt2500usb_fill_rxdone, |
1795 | .beacon_update = rt2500usb_beacon_update, | ||
1796 | .config_filter = rt2500usb_config_filter, | 1762 | .config_filter = rt2500usb_config_filter, |
1797 | .config_intf = rt2500usb_config_intf, | 1763 | .config_intf = rt2500usb_config_intf, |
1798 | .config_erp = rt2500usb_config_erp, | 1764 | .config_erp = rt2500usb_config_erp, |