diff options
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2400pci.c | 89 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500pci.c | 90 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500usb.c | 154 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00.h | 36 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00dev.c | 9 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00lib.h | 8 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00mac.c | 31 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00queue.c | 64 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt61pci.c | 103 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt73usb.c | 115 |
10 files changed, 289 insertions, 410 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 89b874ca6107..027580bfa7c3 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c | |||
@@ -1058,6 +1058,40 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1058 | /* | 1058 | /* |
1059 | * TX data initialization | 1059 | * TX data initialization |
1060 | */ | 1060 | */ |
1061 | static void rt2400pci_write_beacon(struct queue_entry *entry) | ||
1062 | { | ||
1063 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
1064 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | ||
1065 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | ||
1066 | u32 word; | ||
1067 | u32 reg; | ||
1068 | |||
1069 | /* | ||
1070 | * Disable beaconing while we are reloading the beacon data, | ||
1071 | * otherwise we might be sending out invalid data. | ||
1072 | */ | ||
1073 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | ||
1074 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); | ||
1075 | rt2x00_set_field32(®, CSR14_TBCN, 0); | ||
1076 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | ||
1077 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
1078 | |||
1079 | /* | ||
1080 | * Replace rt2x00lib allocated descriptor with the | ||
1081 | * pointer to the _real_ hardware descriptor. | ||
1082 | * After that, map the beacon to DMA and update the | ||
1083 | * descriptor. | ||
1084 | */ | ||
1085 | memcpy(entry_priv->desc, skbdesc->desc, skbdesc->desc_len); | ||
1086 | skbdesc->desc = entry_priv->desc; | ||
1087 | |||
1088 | rt2x00queue_map_txskb(rt2x00dev, entry->skb); | ||
1089 | |||
1090 | rt2x00_desc_read(entry_priv->desc, 1, &word); | ||
1091 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); | ||
1092 | rt2x00_desc_write(entry_priv->desc, 1, word); | ||
1093 | } | ||
1094 | |||
1061 | static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1095 | static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1062 | const enum data_queue_qid queue) | 1096 | const enum data_queue_qid queue) |
1063 | { | 1097 | { |
@@ -1504,59 +1538,6 @@ static u64 rt2400pci_get_tsf(struct ieee80211_hw *hw) | |||
1504 | return tsf; | 1538 | return tsf; |
1505 | } | 1539 | } |
1506 | 1540 | ||
1507 | static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
1508 | { | ||
1509 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
1510 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
1511 | struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); | ||
1512 | struct queue_entry_priv_pci *entry_priv; | ||
1513 | struct skb_frame_desc *skbdesc; | ||
1514 | struct txentry_desc txdesc; | ||
1515 | u32 reg; | ||
1516 | |||
1517 | if (unlikely(!intf->beacon)) | ||
1518 | return -ENOBUFS; | ||
1519 | entry_priv = intf->beacon->priv_data; | ||
1520 | |||
1521 | /* | ||
1522 | * Copy all TX descriptor information into txdesc, | ||
1523 | * after that we are free to use the skb->cb array | ||
1524 | * for our information. | ||
1525 | */ | ||
1526 | intf->beacon->skb = skb; | ||
1527 | rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc); | ||
1528 | |||
1529 | /* | ||
1530 | * Fill in skb descriptor | ||
1531 | */ | ||
1532 | skbdesc = get_skb_frame_desc(skb); | ||
1533 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
1534 | skbdesc->desc = entry_priv->desc; | ||
1535 | skbdesc->desc_len = intf->beacon->queue->desc_size; | ||
1536 | skbdesc->entry = intf->beacon; | ||
1537 | |||
1538 | /* | ||
1539 | * Disable beaconing while we are reloading the beacon data, | ||
1540 | * otherwise we might be sending out invalid data. | ||
1541 | */ | ||
1542 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | ||
1543 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); | ||
1544 | rt2x00_set_field32(®, CSR14_TBCN, 0); | ||
1545 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | ||
1546 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
1547 | |||
1548 | /* | ||
1549 | * Enable beacon generation. | ||
1550 | * Write entire beacon with descriptor to register, | ||
1551 | * and kick the beacon generator. | ||
1552 | */ | ||
1553 | rt2x00queue_map_txskb(rt2x00dev, intf->beacon->skb); | ||
1554 | rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc); | ||
1555 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, QID_BEACON); | ||
1556 | |||
1557 | return 0; | ||
1558 | } | ||
1559 | |||
1560 | static int rt2400pci_tx_last_beacon(struct ieee80211_hw *hw) | 1541 | static int rt2400pci_tx_last_beacon(struct ieee80211_hw *hw) |
1561 | { | 1542 | { |
1562 | struct rt2x00_dev *rt2x00dev = hw->priv; | 1543 | struct rt2x00_dev *rt2x00dev = hw->priv; |
@@ -1598,9 +1579,9 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { | |||
1598 | .link_tuner = rt2400pci_link_tuner, | 1579 | .link_tuner = rt2400pci_link_tuner, |
1599 | .write_tx_desc = rt2400pci_write_tx_desc, | 1580 | .write_tx_desc = rt2400pci_write_tx_desc, |
1600 | .write_tx_data = rt2x00pci_write_tx_data, | 1581 | .write_tx_data = rt2x00pci_write_tx_data, |
1582 | .write_beacon = rt2400pci_write_beacon, | ||
1601 | .kick_tx_queue = rt2400pci_kick_tx_queue, | 1583 | .kick_tx_queue = rt2400pci_kick_tx_queue, |
1602 | .fill_rxdone = rt2400pci_fill_rxdone, | 1584 | .fill_rxdone = rt2400pci_fill_rxdone, |
1603 | .beacon_update = rt2400pci_beacon_update, | ||
1604 | .config_filter = rt2400pci_config_filter, | 1585 | .config_filter = rt2400pci_config_filter, |
1605 | .config_intf = rt2400pci_config_intf, | 1586 | .config_intf = rt2400pci_config_intf, |
1606 | .config_erp = rt2400pci_config_erp, | 1587 | .config_erp = rt2400pci_config_erp, |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index a64bb18322e9..50f9e8f6cd68 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
@@ -1216,6 +1216,40 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1216 | /* | 1216 | /* |
1217 | * TX data initialization | 1217 | * TX data initialization |
1218 | */ | 1218 | */ |
1219 | static void rt2500pci_write_beacon(struct queue_entry *entry) | ||
1220 | { | ||
1221 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
1222 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | ||
1223 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | ||
1224 | u32 word; | ||
1225 | u32 reg; | ||
1226 | |||
1227 | /* | ||
1228 | * Disable beaconing while we are reloading the beacon data, | ||
1229 | * otherwise we might be sending out invalid data. | ||
1230 | */ | ||
1231 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | ||
1232 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); | ||
1233 | rt2x00_set_field32(®, CSR14_TBCN, 0); | ||
1234 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | ||
1235 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
1236 | |||
1237 | /* | ||
1238 | * Replace rt2x00lib allocated descriptor with the | ||
1239 | * pointer to the _real_ hardware descriptor. | ||
1240 | * After that, map the beacon to DMA and update the | ||
1241 | * descriptor. | ||
1242 | */ | ||
1243 | memcpy(entry_priv->desc, skbdesc->desc, skbdesc->desc_len); | ||
1244 | skbdesc->desc = entry_priv->desc; | ||
1245 | |||
1246 | rt2x00queue_map_txskb(rt2x00dev, entry->skb); | ||
1247 | |||
1248 | rt2x00_desc_read(entry_priv->desc, 1, &word); | ||
1249 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); | ||
1250 | rt2x00_desc_write(entry_priv->desc, 1, word); | ||
1251 | } | ||
1252 | |||
1219 | static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1253 | static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1220 | const enum data_queue_qid queue) | 1254 | const enum data_queue_qid queue) |
1221 | { | 1255 | { |
@@ -1797,60 +1831,6 @@ static u64 rt2500pci_get_tsf(struct ieee80211_hw *hw) | |||
1797 | return tsf; | 1831 | return tsf; |
1798 | } | 1832 | } |
1799 | 1833 | ||
1800 | static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
1801 | { | ||
1802 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
1803 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
1804 | struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); | ||
1805 | struct queue_entry_priv_pci *entry_priv; | ||
1806 | struct skb_frame_desc *skbdesc; | ||
1807 | struct txentry_desc txdesc; | ||
1808 | u32 reg; | ||
1809 | |||
1810 | if (unlikely(!intf->beacon)) | ||
1811 | return -ENOBUFS; | ||
1812 | |||
1813 | entry_priv = intf->beacon->priv_data; | ||
1814 | |||
1815 | /* | ||
1816 | * Copy all TX descriptor information into txdesc, | ||
1817 | * after that we are free to use the skb->cb array | ||
1818 | * for our information. | ||
1819 | */ | ||
1820 | intf->beacon->skb = skb; | ||
1821 | rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc); | ||
1822 | |||
1823 | /* | ||
1824 | * Fill in skb descriptor | ||
1825 | */ | ||
1826 | skbdesc = get_skb_frame_desc(skb); | ||
1827 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
1828 | skbdesc->desc = entry_priv->desc; | ||
1829 | skbdesc->desc_len = intf->beacon->queue->desc_size; | ||
1830 | skbdesc->entry = intf->beacon; | ||
1831 | |||
1832 | /* | ||
1833 | * Disable beaconing while we are reloading the beacon data, | ||
1834 | * otherwise we might be sending out invalid data. | ||
1835 | */ | ||
1836 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | ||
1837 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); | ||
1838 | rt2x00_set_field32(®, CSR14_TBCN, 0); | ||
1839 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | ||
1840 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
1841 | |||
1842 | /* | ||
1843 | * Enable beacon generation. | ||
1844 | * Write entire beacon with descriptor to register, | ||
1845 | * and kick the beacon generator. | ||
1846 | */ | ||
1847 | rt2x00queue_map_txskb(rt2x00dev, intf->beacon->skb); | ||
1848 | rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc); | ||
1849 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, QID_BEACON); | ||
1850 | |||
1851 | return 0; | ||
1852 | } | ||
1853 | |||
1854 | static int rt2500pci_tx_last_beacon(struct ieee80211_hw *hw) | 1834 | static int rt2500pci_tx_last_beacon(struct ieee80211_hw *hw) |
1855 | { | 1835 | { |
1856 | struct rt2x00_dev *rt2x00dev = hw->priv; | 1836 | struct rt2x00_dev *rt2x00dev = hw->priv; |
@@ -1892,9 +1872,9 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { | |||
1892 | .link_tuner = rt2500pci_link_tuner, | 1872 | .link_tuner = rt2500pci_link_tuner, |
1893 | .write_tx_desc = rt2500pci_write_tx_desc, | 1873 | .write_tx_desc = rt2500pci_write_tx_desc, |
1894 | .write_tx_data = rt2x00pci_write_tx_data, | 1874 | .write_tx_data = rt2x00pci_write_tx_data, |
1875 | .write_beacon = rt2500pci_write_beacon, | ||
1895 | .kick_tx_queue = rt2500pci_kick_tx_queue, | 1876 | .kick_tx_queue = rt2500pci_kick_tx_queue, |
1896 | .fill_rxdone = rt2500pci_fill_rxdone, | 1877 | .fill_rxdone = rt2500pci_fill_rxdone, |
1897 | .beacon_update = rt2500pci_beacon_update, | ||
1898 | .config_filter = rt2500pci_config_filter, | 1878 | .config_filter = rt2500pci_config_filter, |
1899 | .config_intf = rt2500pci_config_intf, | 1879 | .config_intf = rt2500pci_config_intf, |
1900 | .config_erp = rt2500pci_config_erp, | 1880 | .config_erp = rt2500pci_config_erp, |
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, |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index b32fedf4a1b9..f0d7e083d8f8 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -521,6 +521,7 @@ struct rt2x00lib_ops { | |||
521 | struct sk_buff *skb, | 521 | struct sk_buff *skb, |
522 | struct txentry_desc *txdesc); | 522 | struct txentry_desc *txdesc); |
523 | int (*write_tx_data) (struct queue_entry *entry); | 523 | int (*write_tx_data) (struct queue_entry *entry); |
524 | void (*write_beacon) (struct queue_entry *entry); | ||
524 | int (*get_tx_data_len) (struct rt2x00_dev *rt2x00dev, | 525 | int (*get_tx_data_len) (struct rt2x00_dev *rt2x00dev, |
525 | struct sk_buff *skb); | 526 | struct sk_buff *skb); |
526 | void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev, | 527 | void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev, |
@@ -535,8 +536,6 @@ struct rt2x00lib_ops { | |||
535 | /* | 536 | /* |
536 | * Configuration handlers. | 537 | * Configuration handlers. |
537 | */ | 538 | */ |
538 | int (*beacon_update) (struct ieee80211_hw *hw, struct sk_buff *bcn); | ||
539 | |||
540 | void (*config_filter) (struct rt2x00_dev *rt2x00dev, | 539 | void (*config_filter) (struct rt2x00_dev *rt2x00dev, |
541 | const unsigned int filter_flags); | 540 | const unsigned int filter_flags); |
542 | void (*config_intf) (struct rt2x00_dev *rt2x00dev, | 541 | void (*config_intf) (struct rt2x00_dev *rt2x00dev, |
@@ -913,39 +912,6 @@ static inline u16 get_duration_res(const unsigned int size, const u8 rate) | |||
913 | void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); | 912 | void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); |
914 | 913 | ||
915 | /** | 914 | /** |
916 | * rt2x00queue_create_tx_descriptor - Create TX descriptor from mac80211 input | ||
917 | * @entry: The entry which will be used to transfer the TX frame. | ||
918 | * @txdesc: rt2x00 TX descriptor which will be initialized by this function. | ||
919 | * | ||
920 | * This function will initialize the &struct txentry_desc based on information | ||
921 | * from mac80211. This descriptor can then be used by rt2x00lib and the drivers | ||
922 | * to correctly initialize the hardware descriptor. | ||
923 | * Note that before calling this function the skb->cb array must be untouched | ||
924 | * by rt2x00lib. Only after this function completes will it be save to | ||
925 | * overwrite the skb->cb information. | ||
926 | * The reason for this is that mac80211 writes its own tx information into | ||
927 | * the skb->cb array, and this function will use that information to initialize | ||
928 | * the &struct txentry_desc structure. | ||
929 | */ | ||
930 | void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | ||
931 | struct txentry_desc *txdesc); | ||
932 | |||
933 | /** | ||
934 | * rt2x00queue_write_tx_descriptor - Write TX descriptor to hardware | ||
935 | * @entry: The entry which will be used to transfer the TX frame. | ||
936 | * @txdesc: TX descriptor which will be used to write hardware descriptor | ||
937 | * | ||
938 | * This function will write a TX descriptor initialized by | ||
939 | * &rt2x00queue_create_tx_descriptor to the hardware. After this call | ||
940 | * has completed the frame is now owned by the hardware, the hardware | ||
941 | * queue will have automatically be kicked unless this frame was generated | ||
942 | * by rt2x00lib, in which case the frame is "special" and must be kicked | ||
943 | * by the caller. | ||
944 | */ | ||
945 | void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, | ||
946 | struct txentry_desc *txdesc); | ||
947 | |||
948 | /** | ||
949 | * rt2x00queue_get_queue - Convert queue index to queue pointer | 915 | * rt2x00queue_get_queue - Convert queue index to queue pointer |
950 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | 916 | * @rt2x00dev: Pointer to &struct rt2x00_dev. |
951 | * @queue: rt2x00 queue index (see &enum data_queue_qid). | 917 | * @queue: rt2x00 queue index (see &enum data_queue_qid). |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 1b7f87799a7e..8c93eb8353b0 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -434,13 +434,8 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac, | |||
434 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) | 434 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) |
435 | return; | 435 | return; |
436 | 436 | ||
437 | if (delayed_flags & DELAYED_UPDATE_BEACON) { | 437 | if (delayed_flags & DELAYED_UPDATE_BEACON) |
438 | struct ieee80211_if_conf conf; | 438 | rt2x00queue_update_beacon(rt2x00dev, vif); |
439 | conf.bssid = conf.ssid = NULL; | ||
440 | conf.ssid_len = 0; | ||
441 | conf.changed = IEEE80211_IFCC_BEACON; | ||
442 | rt2x00dev->ops->hw->config_interface(rt2x00dev->hw, vif, &conf); | ||
443 | } | ||
444 | 439 | ||
445 | if (delayed_flags & DELAYED_CONFIG_ERP) | 440 | if (delayed_flags & DELAYED_CONFIG_ERP) |
446 | rt2x00lib_config_erp(rt2x00dev, intf, &conf); | 441 | rt2x00lib_config_erp(rt2x00dev, intf, &conf); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index eae5ce1d4de3..f2c9b0e79b5f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h | |||
@@ -139,6 +139,14 @@ void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); | |||
139 | int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb); | 139 | int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb); |
140 | 140 | ||
141 | /** | 141 | /** |
142 | * rt2x00queue_update_beacon - Send new beacon from mac80211 to hardware | ||
143 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | ||
144 | * @vif: Interface for which the beacon should be updated. | ||
145 | */ | ||
146 | int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, | ||
147 | struct ieee80211_vif *vif); | ||
148 | |||
149 | /** | ||
142 | * rt2x00queue_index_inc - Index incrementation function | 150 | * rt2x00queue_index_inc - Index incrementation function |
143 | * @queue: Queue (&struct data_queue) to perform the action on. | 151 | * @queue: Queue (&struct data_queue) to perform the action on. |
144 | * @index: Index type (&enum queue_index) to perform the action on. | 152 | * @index: Index type (&enum queue_index) to perform the action on. |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index ff853c430bdf..16b72d9ca1c3 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -348,8 +348,8 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw, | |||
348 | { | 348 | { |
349 | struct rt2x00_dev *rt2x00dev = hw->priv; | 349 | struct rt2x00_dev *rt2x00dev = hw->priv; |
350 | struct rt2x00_intf *intf = vif_to_intf(vif); | 350 | struct rt2x00_intf *intf = vif_to_intf(vif); |
351 | struct sk_buff *beacon; | 351 | int update_bssid = 0; |
352 | int status; | 352 | int status = 0; |
353 | 353 | ||
354 | /* | 354 | /* |
355 | * Mac80211 might be calling this function while we are trying | 355 | * Mac80211 might be calling this function while we are trying |
@@ -361,15 +361,13 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw, | |||
361 | spin_lock(&intf->lock); | 361 | spin_lock(&intf->lock); |
362 | 362 | ||
363 | /* | 363 | /* |
364 | * If the interface does not work in master mode, | ||
365 | * then the bssid value in the interface structure | ||
366 | * should now be set. | ||
367 | * | ||
368 | * conf->bssid can be NULL if coming from the internal | 364 | * conf->bssid can be NULL if coming from the internal |
369 | * beacon update routine. | 365 | * beacon update routine. |
370 | */ | 366 | */ |
371 | if (conf->bssid && vif->type != IEEE80211_IF_TYPE_AP) | 367 | if (conf->changed & IEEE80211_IFCC_BSSID && conf->bssid) { |
368 | update_bssid = 1; | ||
372 | memcpy(&intf->bssid, conf->bssid, ETH_ALEN); | 369 | memcpy(&intf->bssid, conf->bssid, ETH_ALEN); |
370 | } | ||
373 | 371 | ||
374 | spin_unlock(&intf->lock); | 372 | spin_unlock(&intf->lock); |
375 | 373 | ||
@@ -379,23 +377,14 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw, | |||
379 | * values as arguments we make keep access to rt2x00_intf thread safe | 377 | * values as arguments we make keep access to rt2x00_intf thread safe |
380 | * even without the lock. | 378 | * even without the lock. |
381 | */ | 379 | */ |
382 | rt2x00lib_config_intf(rt2x00dev, intf, vif->type, NULL, conf->bssid); | 380 | rt2x00lib_config_intf(rt2x00dev, intf, vif->type, NULL, |
381 | update_bssid ? conf->bssid : NULL); | ||
383 | 382 | ||
384 | /* | 383 | /* |
385 | * We only need to initialize the beacon when in master/ibss mode. | 384 | * Update the beacon. |
386 | */ | 385 | */ |
387 | if ((vif->type != IEEE80211_IF_TYPE_AP && | 386 | if (conf->changed & IEEE80211_IFCC_BEACON) |
388 | vif->type != IEEE80211_IF_TYPE_IBSS) || | 387 | status = rt2x00queue_update_beacon(rt2x00dev, vif); |
389 | !(conf->changed & IEEE80211_IFCC_BEACON)) | ||
390 | return 0; | ||
391 | |||
392 | beacon = ieee80211_beacon_get(rt2x00dev->hw, vif); | ||
393 | if (!beacon) | ||
394 | return -ENOMEM; | ||
395 | |||
396 | status = rt2x00dev->ops->lib->beacon_update(rt2x00dev->hw, beacon); | ||
397 | if (status) | ||
398 | dev_kfree_skb(beacon); | ||
399 | 388 | ||
400 | return status; | 389 | return status; |
401 | } | 390 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index ecf57f8f34b2..7f442030f5ad 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -115,8 +115,8 @@ void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) | |||
115 | dev_kfree_skb_any(skb); | 115 | dev_kfree_skb_any(skb); |
116 | } | 116 | } |
117 | 117 | ||
118 | void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | 118 | static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, |
119 | struct txentry_desc *txdesc) | 119 | struct txentry_desc *txdesc) |
120 | { | 120 | { |
121 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 121 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
122 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); | 122 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); |
@@ -240,10 +240,9 @@ void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | |||
240 | txdesc->signal |= 0x08; | 240 | txdesc->signal |= 0x08; |
241 | } | 241 | } |
242 | } | 242 | } |
243 | EXPORT_SYMBOL_GPL(rt2x00queue_create_tx_descriptor); | ||
244 | 243 | ||
245 | void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, | 244 | static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, |
246 | struct txentry_desc *txdesc) | 245 | struct txentry_desc *txdesc) |
247 | { | 246 | { |
248 | struct data_queue *queue = entry->queue; | 247 | struct data_queue *queue = entry->queue; |
249 | struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; | 248 | struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; |
@@ -273,7 +272,6 @@ void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, | |||
273 | !test_bit(ENTRY_TXD_BURST, &txdesc->flags)) | 272 | !test_bit(ENTRY_TXD_BURST, &txdesc->flags)) |
274 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, queue->qid); | 273 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, queue->qid); |
275 | } | 274 | } |
276 | EXPORT_SYMBOL_GPL(rt2x00queue_write_tx_descriptor); | ||
277 | 275 | ||
278 | int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb) | 276 | int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb) |
279 | { | 277 | { |
@@ -323,6 +321,60 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb) | |||
323 | return 0; | 321 | return 0; |
324 | } | 322 | } |
325 | 323 | ||
324 | int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, | ||
325 | struct ieee80211_vif *vif) | ||
326 | { | ||
327 | struct rt2x00_intf *intf = vif_to_intf(vif); | ||
328 | struct skb_frame_desc *skbdesc; | ||
329 | struct txentry_desc txdesc; | ||
330 | __le32 desc[16]; | ||
331 | |||
332 | if (unlikely(!intf->beacon)) | ||
333 | return -ENOBUFS; | ||
334 | |||
335 | intf->beacon->skb = ieee80211_beacon_get(rt2x00dev->hw, vif); | ||
336 | if (!intf->beacon->skb) | ||
337 | return -ENOMEM; | ||
338 | |||
339 | /* | ||
340 | * Copy all TX descriptor information into txdesc, | ||
341 | * after that we are free to use the skb->cb array | ||
342 | * for our information. | ||
343 | */ | ||
344 | rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc); | ||
345 | |||
346 | /* | ||
347 | * For the descriptor we use a local array from where the | ||
348 | * driver can move it to the correct location required for | ||
349 | * the hardware. | ||
350 | */ | ||
351 | memset(desc, 0, sizeof(desc)); | ||
352 | |||
353 | /* | ||
354 | * Fill in skb descriptor | ||
355 | */ | ||
356 | skbdesc = get_skb_frame_desc(intf->beacon->skb); | ||
357 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
358 | skbdesc->desc = desc; | ||
359 | skbdesc->desc_len = intf->beacon->queue->desc_size; | ||
360 | skbdesc->entry = intf->beacon; | ||
361 | |||
362 | /* | ||
363 | * Write TX descriptor into reserved room in front of the beacon. | ||
364 | */ | ||
365 | rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc); | ||
366 | |||
367 | /* | ||
368 | * Send beacon to hardware. | ||
369 | * Also enable beacon generation, which might have been disabled | ||
370 | * by the driver during the config_beacon() callback function. | ||
371 | */ | ||
372 | rt2x00dev->ops->lib->write_beacon(intf->beacon); | ||
373 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, QID_BEACON); | ||
374 | |||
375 | return 0; | ||
376 | } | ||
377 | |||
326 | struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, | 378 | struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, |
327 | const enum data_queue_qid queue) | 379 | const enum data_queue_qid queue) |
328 | { | 380 | { |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 852d193a11a9..80c4445e6286 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -1591,6 +1591,41 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1591 | /* | 1591 | /* |
1592 | * TX data initialization | 1592 | * TX data initialization |
1593 | */ | 1593 | */ |
1594 | static void rt61pci_write_beacon(struct queue_entry *entry) | ||
1595 | { | ||
1596 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
1597 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | ||
1598 | unsigned int beacon_base; | ||
1599 | u32 reg; | ||
1600 | |||
1601 | /* | ||
1602 | * Disable beaconing while we are reloading the beacon data, | ||
1603 | * otherwise we might be sending out invalid data. | ||
1604 | */ | ||
1605 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
1606 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); | ||
1607 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); | ||
1608 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
1609 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
1610 | |||
1611 | /* | ||
1612 | * Write entire beacon with descriptor to register. | ||
1613 | */ | ||
1614 | beacon_base = HW_BEACON_OFFSET(entry->entry_idx); | ||
1615 | rt2x00pci_register_multiwrite(rt2x00dev, | ||
1616 | beacon_base, | ||
1617 | skbdesc->desc, skbdesc->desc_len); | ||
1618 | rt2x00pci_register_multiwrite(rt2x00dev, | ||
1619 | beacon_base + skbdesc->desc_len, | ||
1620 | entry->skb->data, entry->skb->len); | ||
1621 | |||
1622 | /* | ||
1623 | * Clean up beacon skb. | ||
1624 | */ | ||
1625 | dev_kfree_skb_any(entry->skb); | ||
1626 | entry->skb = NULL; | ||
1627 | } | ||
1628 | |||
1594 | static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1629 | static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1595 | const enum data_queue_qid queue) | 1630 | const enum data_queue_qid queue) |
1596 | { | 1631 | { |
@@ -2346,72 +2381,6 @@ static u64 rt61pci_get_tsf(struct ieee80211_hw *hw) | |||
2346 | return tsf; | 2381 | return tsf; |
2347 | } | 2382 | } |
2348 | 2383 | ||
2349 | static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
2350 | { | ||
2351 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
2352 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
2353 | struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); | ||
2354 | struct queue_entry_priv_pci *entry_priv; | ||
2355 | struct skb_frame_desc *skbdesc; | ||
2356 | struct txentry_desc txdesc; | ||
2357 | unsigned int beacon_base; | ||
2358 | u32 reg; | ||
2359 | |||
2360 | if (unlikely(!intf->beacon)) | ||
2361 | return -ENOBUFS; | ||
2362 | |||
2363 | /* | ||
2364 | * Copy all TX descriptor information into txdesc, | ||
2365 | * after that we are free to use the skb->cb array | ||
2366 | * for our information. | ||
2367 | */ | ||
2368 | intf->beacon->skb = skb; | ||
2369 | rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc); | ||
2370 | |||
2371 | entry_priv = intf->beacon->priv_data; | ||
2372 | memset(entry_priv->desc, 0, intf->beacon->queue->desc_size); | ||
2373 | |||
2374 | /* | ||
2375 | * Fill in skb descriptor | ||
2376 | */ | ||
2377 | skbdesc = get_skb_frame_desc(skb); | ||
2378 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
2379 | skbdesc->desc = entry_priv->desc; | ||
2380 | skbdesc->desc_len = intf->beacon->queue->desc_size; | ||
2381 | skbdesc->entry = intf->beacon; | ||
2382 | |||
2383 | /* | ||
2384 | * Disable beaconing while we are reloading the beacon data, | ||
2385 | * otherwise we might be sending out invalid data. | ||
2386 | */ | ||
2387 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
2388 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); | ||
2389 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); | ||
2390 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
2391 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
2392 | |||
2393 | /* | ||
2394 | * Write entire beacon with descriptor to register, | ||
2395 | * and kick the beacon generator. | ||
2396 | */ | ||
2397 | rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc); | ||
2398 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); | ||
2399 | rt2x00pci_register_multiwrite(rt2x00dev, beacon_base, | ||
2400 | skbdesc->desc, skbdesc->desc_len); | ||
2401 | rt2x00pci_register_multiwrite(rt2x00dev, | ||
2402 | beacon_base + skbdesc->desc_len, | ||
2403 | skb->data, skb->len); | ||
2404 | rt61pci_kick_tx_queue(rt2x00dev, QID_BEACON); | ||
2405 | |||
2406 | /* | ||
2407 | * Clean up beacon skb. | ||
2408 | */ | ||
2409 | dev_kfree_skb_any(skb); | ||
2410 | intf->beacon->skb = NULL; | ||
2411 | |||
2412 | return 0; | ||
2413 | } | ||
2414 | |||
2415 | static const struct ieee80211_ops rt61pci_mac80211_ops = { | 2384 | static const struct ieee80211_ops rt61pci_mac80211_ops = { |
2416 | .tx = rt2x00mac_tx, | 2385 | .tx = rt2x00mac_tx, |
2417 | .start = rt2x00mac_start, | 2386 | .start = rt2x00mac_start, |
@@ -2446,9 +2415,9 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { | |||
2446 | .link_tuner = rt61pci_link_tuner, | 2415 | .link_tuner = rt61pci_link_tuner, |
2447 | .write_tx_desc = rt61pci_write_tx_desc, | 2416 | .write_tx_desc = rt61pci_write_tx_desc, |
2448 | .write_tx_data = rt2x00pci_write_tx_data, | 2417 | .write_tx_data = rt2x00pci_write_tx_data, |
2418 | .write_beacon = rt61pci_write_beacon, | ||
2449 | .kick_tx_queue = rt61pci_kick_tx_queue, | 2419 | .kick_tx_queue = rt61pci_kick_tx_queue, |
2450 | .fill_rxdone = rt61pci_fill_rxdone, | 2420 | .fill_rxdone = rt61pci_fill_rxdone, |
2451 | .beacon_update = rt61pci_beacon_update, | ||
2452 | .config_filter = rt61pci_config_filter, | 2421 | .config_filter = rt61pci_config_filter, |
2453 | .config_intf = rt61pci_config_intf, | 2422 | .config_intf = rt61pci_config_intf, |
2454 | .config_erp = rt61pci_config_erp, | 2423 | .config_erp = rt61pci_config_erp, |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 657200972424..6f89b4c75e1f 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -1334,6 +1334,49 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1334 | rt2x00_desc_write(txd, 0, word); | 1334 | rt2x00_desc_write(txd, 0, word); |
1335 | } | 1335 | } |
1336 | 1336 | ||
1337 | /* | ||
1338 | * TX data initialization | ||
1339 | */ | ||
1340 | static void rt73usb_write_beacon(struct queue_entry *entry) | ||
1341 | { | ||
1342 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
1343 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | ||
1344 | unsigned int beacon_base; | ||
1345 | u32 reg; | ||
1346 | |||
1347 | /* | ||
1348 | * Add the descriptor in front of the skb. | ||
1349 | */ | ||
1350 | skb_push(entry->skb, entry->queue->desc_size); | ||
1351 | memcpy(entry->skb->data, skbdesc->desc, skbdesc->desc_len); | ||
1352 | skbdesc->desc = entry->skb->data; | ||
1353 | |||
1354 | /* | ||
1355 | * Disable beaconing while we are reloading the beacon data, | ||
1356 | * otherwise we might be sending out invalid data. | ||
1357 | */ | ||
1358 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
1359 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); | ||
1360 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); | ||
1361 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
1362 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
1363 | |||
1364 | /* | ||
1365 | * Write entire beacon with descriptor to register. | ||
1366 | */ | ||
1367 | beacon_base = HW_BEACON_OFFSET(entry->entry_idx); | ||
1368 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, | ||
1369 | USB_VENDOR_REQUEST_OUT, beacon_base, 0, | ||
1370 | entry->skb->data, entry->skb->len, | ||
1371 | REGISTER_TIMEOUT32(entry->skb->len)); | ||
1372 | |||
1373 | /* | ||
1374 | * Clean up the beacon skb. | ||
1375 | */ | ||
1376 | dev_kfree_skb(entry->skb); | ||
1377 | entry->skb = NULL; | ||
1378 | } | ||
1379 | |||
1337 | static int rt73usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev, | 1380 | static int rt73usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev, |
1338 | struct sk_buff *skb) | 1381 | struct sk_buff *skb) |
1339 | { | 1382 | { |
@@ -1349,9 +1392,6 @@ static int rt73usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev, | |||
1349 | return length; | 1392 | return length; |
1350 | } | 1393 | } |
1351 | 1394 | ||
1352 | /* | ||
1353 | * TX data initialization | ||
1354 | */ | ||
1355 | static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1395 | static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1356 | const enum data_queue_qid queue) | 1396 | const enum data_queue_qid queue) |
1357 | { | 1397 | { |
@@ -1949,73 +1989,6 @@ static u64 rt73usb_get_tsf(struct ieee80211_hw *hw) | |||
1949 | #define rt73usb_get_tsf NULL | 1989 | #define rt73usb_get_tsf NULL |
1950 | #endif | 1990 | #endif |
1951 | 1991 | ||
1952 | static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
1953 | { | ||
1954 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
1955 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
1956 | struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); | ||
1957 | struct skb_frame_desc *skbdesc; | ||
1958 | struct txentry_desc txdesc; | ||
1959 | unsigned int beacon_base; | ||
1960 | u32 reg; | ||
1961 | |||
1962 | if (unlikely(!intf->beacon)) | ||
1963 | return -ENOBUFS; | ||
1964 | |||
1965 | /* | ||
1966 | * Copy all TX descriptor information into txdesc, | ||
1967 | * after that we are free to use the skb->cb array | ||
1968 | * for our information. | ||
1969 | */ | ||
1970 | intf->beacon->skb = skb; | ||
1971 | rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc); | ||
1972 | |||
1973 | /* | ||
1974 | * Add the descriptor in front of the skb. | ||
1975 | */ | ||
1976 | skb_push(skb, intf->beacon->queue->desc_size); | ||
1977 | memset(skb->data, 0, intf->beacon->queue->desc_size); | ||
1978 | |||
1979 | /* | ||
1980 | * Fill in skb descriptor | ||
1981 | */ | ||
1982 | skbdesc = get_skb_frame_desc(skb); | ||
1983 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
1984 | skbdesc->desc = skb->data; | ||
1985 | skbdesc->desc_len = intf->beacon->queue->desc_size; | ||
1986 | skbdesc->entry = intf->beacon; | ||
1987 | |||
1988 | /* | ||
1989 | * Disable beaconing while we are reloading the beacon data, | ||
1990 | * otherwise we might be sending out invalid data. | ||
1991 | */ | ||
1992 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
1993 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); | ||
1994 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); | ||
1995 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
1996 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
1997 | |||
1998 | /* | ||
1999 | * Write entire beacon with descriptor to register, | ||
2000 | * and kick the beacon generator. | ||
2001 | */ | ||
2002 | rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc); | ||
2003 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); | ||
2004 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, | ||
2005 | USB_VENDOR_REQUEST_OUT, beacon_base, 0, | ||
2006 | skb->data, skb->len, | ||
2007 | REGISTER_TIMEOUT32(skb->len)); | ||
2008 | rt73usb_kick_tx_queue(rt2x00dev, QID_BEACON); | ||
2009 | |||
2010 | /* | ||
2011 | * Clean up the beacon skb. | ||
2012 | */ | ||
2013 | dev_kfree_skb(skb); | ||
2014 | intf->beacon->skb = NULL; | ||
2015 | |||
2016 | return 0; | ||
2017 | } | ||
2018 | |||
2019 | static const struct ieee80211_ops rt73usb_mac80211_ops = { | 1992 | static const struct ieee80211_ops rt73usb_mac80211_ops = { |
2020 | .tx = rt2x00mac_tx, | 1993 | .tx = rt2x00mac_tx, |
2021 | .start = rt2x00mac_start, | 1994 | .start = rt2x00mac_start, |
@@ -2048,10 +2021,10 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { | |||
2048 | .link_tuner = rt73usb_link_tuner, | 2021 | .link_tuner = rt73usb_link_tuner, |
2049 | .write_tx_desc = rt73usb_write_tx_desc, | 2022 | .write_tx_desc = rt73usb_write_tx_desc, |
2050 | .write_tx_data = rt2x00usb_write_tx_data, | 2023 | .write_tx_data = rt2x00usb_write_tx_data, |
2024 | .write_beacon = rt73usb_write_beacon, | ||
2051 | .get_tx_data_len = rt73usb_get_tx_data_len, | 2025 | .get_tx_data_len = rt73usb_get_tx_data_len, |
2052 | .kick_tx_queue = rt73usb_kick_tx_queue, | 2026 | .kick_tx_queue = rt73usb_kick_tx_queue, |
2053 | .fill_rxdone = rt73usb_fill_rxdone, | 2027 | .fill_rxdone = rt73usb_fill_rxdone, |
2054 | .beacon_update = rt73usb_beacon_update, | ||
2055 | .config_filter = rt73usb_config_filter, | 2028 | .config_filter = rt73usb_config_filter, |
2056 | .config_intf = rt73usb_config_intf, | 2029 | .config_intf = rt73usb_config_intf, |
2057 | .config_erp = rt73usb_config_erp, | 2030 | .config_erp = rt73usb_config_erp, |