diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2500usb.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500usb.c | 85 |
1 files changed, 43 insertions, 42 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 88bafdf8f0fa..cca1504550dc 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -1033,8 +1033,7 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1033 | */ | 1033 | */ |
1034 | static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 1034 | static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, |
1035 | struct sk_buff *skb, | 1035 | struct sk_buff *skb, |
1036 | struct txentry_desc *txdesc, | 1036 | struct txentry_desc *txdesc) |
1037 | struct ieee80211_tx_control *control) | ||
1038 | { | 1037 | { |
1039 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | 1038 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
1040 | __le32 *txd = skbdesc->desc; | 1039 | __le32 *txd = skbdesc->desc; |
@@ -1058,7 +1057,7 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1058 | rt2x00_desc_write(txd, 2, word); | 1057 | rt2x00_desc_write(txd, 2, word); |
1059 | 1058 | ||
1060 | rt2x00_desc_read(txd, 0, &word); | 1059 | rt2x00_desc_read(txd, 0, &word); |
1061 | rt2x00_set_field32(&word, TXD_W0_RETRY_LIMIT, control->retry_limit); | 1060 | rt2x00_set_field32(&word, TXD_W0_RETRY_LIMIT, txdesc->retry_limit); |
1062 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, | 1061 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, |
1063 | test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); | 1062 | test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); |
1064 | rt2x00_set_field32(&word, TXD_W0_ACK, | 1063 | rt2x00_set_field32(&word, TXD_W0_ACK, |
@@ -1068,7 +1067,7 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1068 | rt2x00_set_field32(&word, TXD_W0_OFDM, | 1067 | rt2x00_set_field32(&word, TXD_W0_OFDM, |
1069 | test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags)); | 1068 | test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags)); |
1070 | rt2x00_set_field32(&word, TXD_W0_NEW_SEQ, | 1069 | rt2x00_set_field32(&word, TXD_W0_NEW_SEQ, |
1071 | !!(control->flags & IEEE80211_TXCTL_FIRST_FRAGMENT)); | 1070 | test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)); |
1072 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); | 1071 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1073 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); | 1072 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); |
1074 | rt2x00_set_field32(&word, TXD_W0_CIPHER, CIPHER_NONE); | 1073 | rt2x00_set_field32(&word, TXD_W0_CIPHER, CIPHER_NONE); |
@@ -1125,30 +1124,32 @@ static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1125 | static void rt2500usb_fill_rxdone(struct queue_entry *entry, | 1124 | static void rt2500usb_fill_rxdone(struct queue_entry *entry, |
1126 | struct rxdone_entry_desc *rxdesc) | 1125 | struct rxdone_entry_desc *rxdesc) |
1127 | { | 1126 | { |
1128 | struct queue_entry_priv_usb_rx *priv_rx = entry->priv_data; | 1127 | struct queue_entry_priv_usb *entry_priv = entry->priv_data; |
1129 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | 1128 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
1130 | __le32 *rxd = | 1129 | __le32 *rxd = |
1131 | (__le32 *)(entry->skb->data + | 1130 | (__le32 *)(entry->skb->data + |
1132 | (priv_rx->urb->actual_length - entry->queue->desc_size)); | 1131 | (entry_priv->urb->actual_length - |
1133 | unsigned int offset = entry->queue->desc_size + 2; | 1132 | entry->queue->desc_size)); |
1134 | u32 word0; | 1133 | u32 word0; |
1135 | u32 word1; | 1134 | u32 word1; |
1136 | 1135 | ||
1137 | /* | 1136 | /* |
1138 | * Copy descriptor to the available headroom inside the skbuffer. | 1137 | * Copy descriptor to the skb->cb array, this has 2 benefits: |
1138 | * 1) Each descriptor word is 4 byte aligned. | ||
1139 | * 2) Descriptor is safe from moving of frame data in rt2x00usb. | ||
1139 | */ | 1140 | */ |
1140 | skb_push(entry->skb, offset); | 1141 | skbdesc->desc_len = |
1141 | memcpy(entry->skb->data, rxd, entry->queue->desc_size); | 1142 | min_t(u16, entry->queue->desc_size, sizeof(entry->skb->cb)); |
1142 | rxd = (__le32 *)entry->skb->data; | 1143 | memcpy(entry->skb->cb, rxd, skbdesc->desc_len); |
1144 | skbdesc->desc = entry->skb->cb; | ||
1145 | rxd = (__le32 *)skbdesc->desc; | ||
1143 | 1146 | ||
1144 | /* | 1147 | /* |
1145 | * The descriptor is now aligned to 4 bytes and thus it is | 1148 | * It is now safe to read the descriptor on all architectures. |
1146 | * now safe to read it on all architectures. | ||
1147 | */ | 1149 | */ |
1148 | rt2x00_desc_read(rxd, 0, &word0); | 1150 | rt2x00_desc_read(rxd, 0, &word0); |
1149 | rt2x00_desc_read(rxd, 1, &word1); | 1151 | rt2x00_desc_read(rxd, 1, &word1); |
1150 | 1152 | ||
1151 | rxdesc->flags = 0; | ||
1152 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) | 1153 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) |
1153 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; | 1154 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; |
1154 | if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) | 1155 | if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) |
@@ -1165,7 +1166,6 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry, | |||
1165 | entry->queue->rt2x00dev->rssi_offset; | 1166 | entry->queue->rt2x00dev->rssi_offset; |
1166 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | 1167 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); |
1167 | 1168 | ||
1168 | rxdesc->dev_flags = 0; | ||
1169 | if (rt2x00_get_field32(word0, RXD_W0_OFDM)) | 1169 | if (rt2x00_get_field32(word0, RXD_W0_OFDM)) |
1170 | rxdesc->dev_flags |= RXDONE_SIGNAL_PLCP; | 1170 | rxdesc->dev_flags |= RXDONE_SIGNAL_PLCP; |
1171 | if (rt2x00_get_field32(word0, RXD_W0_MY_BSS)) | 1171 | if (rt2x00_get_field32(word0, RXD_W0_MY_BSS)) |
@@ -1174,16 +1174,9 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry, | |||
1174 | /* | 1174 | /* |
1175 | * Adjust the skb memory window to the frame boundaries. | 1175 | * Adjust the skb memory window to the frame boundaries. |
1176 | */ | 1176 | */ |
1177 | skb_pull(entry->skb, offset); | ||
1178 | skb_trim(entry->skb, rxdesc->size); | 1177 | skb_trim(entry->skb, rxdesc->size); |
1179 | |||
1180 | /* | ||
1181 | * Set descriptor and data pointer. | ||
1182 | */ | ||
1183 | skbdesc->data = entry->skb->data; | 1178 | skbdesc->data = entry->skb->data; |
1184 | skbdesc->data_len = rxdesc->size; | 1179 | skbdesc->data_len = rxdesc->size; |
1185 | skbdesc->desc = rxd; | ||
1186 | skbdesc->desc_len = entry->queue->desc_size; | ||
1187 | } | 1180 | } |
1188 | 1181 | ||
1189 | /* | 1182 | /* |
@@ -1192,7 +1185,7 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry, | |||
1192 | static void rt2500usb_beacondone(struct urb *urb) | 1185 | static void rt2500usb_beacondone(struct urb *urb) |
1193 | { | 1186 | { |
1194 | struct queue_entry *entry = (struct queue_entry *)urb->context; | 1187 | struct queue_entry *entry = (struct queue_entry *)urb->context; |
1195 | struct queue_entry_priv_usb_bcn *priv_bcn = entry->priv_data; | 1188 | struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data; |
1196 | 1189 | ||
1197 | if (!test_bit(DEVICE_ENABLED_RADIO, &entry->queue->rt2x00dev->flags)) | 1190 | if (!test_bit(DEVICE_ENABLED_RADIO, &entry->queue->rt2x00dev->flags)) |
1198 | return; | 1191 | return; |
@@ -1203,9 +1196,9 @@ static void rt2500usb_beacondone(struct urb *urb) | |||
1203 | * Otherwise we should free the sk_buffer, the device | 1196 | * Otherwise we should free the sk_buffer, the device |
1204 | * should be doing the rest of the work now. | 1197 | * should be doing the rest of the work now. |
1205 | */ | 1198 | */ |
1206 | if (priv_bcn->guardian_urb == urb) { | 1199 | if (bcn_priv->guardian_urb == urb) { |
1207 | usb_submit_urb(priv_bcn->urb, GFP_ATOMIC); | 1200 | usb_submit_urb(bcn_priv->urb, GFP_ATOMIC); |
1208 | } else if (priv_bcn->urb == urb) { | 1201 | } else if (bcn_priv->urb == urb) { |
1209 | dev_kfree_skb(entry->skb); | 1202 | dev_kfree_skb(entry->skb); |
1210 | entry->skb = NULL; | 1203 | entry->skb = NULL; |
1211 | } | 1204 | } |
@@ -1591,7 +1584,6 @@ static void rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1591 | IEEE80211_HW_SIGNAL_DBM; | 1584 | IEEE80211_HW_SIGNAL_DBM; |
1592 | 1585 | ||
1593 | rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; | 1586 | rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; |
1594 | rt2x00dev->hw->queues = 2; | ||
1595 | 1587 | ||
1596 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev); | 1588 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev); |
1597 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, | 1589 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, |
@@ -1674,15 +1666,15 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1674 | /* | 1666 | /* |
1675 | * IEEE80211 stack callback functions. | 1667 | * IEEE80211 stack callback functions. |
1676 | */ | 1668 | */ |
1677 | static int rt2500usb_beacon_update(struct ieee80211_hw *hw, | 1669 | static int rt2500usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) |
1678 | struct sk_buff *skb, | ||
1679 | struct ieee80211_tx_control *control) | ||
1680 | { | 1670 | { |
1681 | struct rt2x00_dev *rt2x00dev = hw->priv; | 1671 | struct rt2x00_dev *rt2x00dev = hw->priv; |
1682 | struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); | 1672 | struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); |
1683 | struct rt2x00_intf *intf = vif_to_intf(control->vif); | 1673 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1684 | struct queue_entry_priv_usb_bcn *priv_bcn; | 1674 | struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); |
1675 | struct queue_entry_priv_usb_bcn *bcn_priv; | ||
1685 | struct skb_frame_desc *skbdesc; | 1676 | struct skb_frame_desc *skbdesc; |
1677 | struct txentry_desc txdesc; | ||
1686 | int pipe = usb_sndbulkpipe(usb_dev, 1); | 1678 | int pipe = usb_sndbulkpipe(usb_dev, 1); |
1687 | int length; | 1679 | int length; |
1688 | u16 reg; | 1680 | u16 reg; |
@@ -1690,7 +1682,15 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw, | |||
1690 | if (unlikely(!intf->beacon)) | 1682 | if (unlikely(!intf->beacon)) |
1691 | return -ENOBUFS; | 1683 | return -ENOBUFS; |
1692 | 1684 | ||
1693 | priv_bcn = intf->beacon->priv_data; | 1685 | bcn_priv = intf->beacon->priv_data; |
1686 | |||
1687 | /* | ||
1688 | * Copy all TX descriptor information into txdesc, | ||
1689 | * after that we are free to use the skb->cb array | ||
1690 | * for our information. | ||
1691 | */ | ||
1692 | intf->beacon->skb = skb; | ||
1693 | rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc); | ||
1694 | 1694 | ||
1695 | /* | 1695 | /* |
1696 | * Add the descriptor in front of the skb. | 1696 | * Add the descriptor in front of the skb. |
@@ -1720,7 +1720,7 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw, | |||
1720 | rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 0); | 1720 | rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 0); |
1721 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); | 1721 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); |
1722 | 1722 | ||
1723 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | 1723 | rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc); |
1724 | 1724 | ||
1725 | /* | 1725 | /* |
1726 | * USB devices cannot blindly pass the skb->len as the | 1726 | * USB devices cannot blindly pass the skb->len as the |
@@ -1729,7 +1729,7 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw, | |||
1729 | */ | 1729 | */ |
1730 | length = rt2500usb_get_tx_data_len(rt2x00dev, skb); | 1730 | length = rt2500usb_get_tx_data_len(rt2x00dev, skb); |
1731 | 1731 | ||
1732 | usb_fill_bulk_urb(priv_bcn->urb, usb_dev, pipe, | 1732 | usb_fill_bulk_urb(bcn_priv->urb, usb_dev, pipe, |
1733 | skb->data, length, rt2500usb_beacondone, | 1733 | skb->data, length, rt2500usb_beacondone, |
1734 | intf->beacon); | 1734 | intf->beacon); |
1735 | 1735 | ||
@@ -1738,15 +1738,15 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw, | |||
1738 | * We only need a single byte, so lets recycle | 1738 | * We only need a single byte, so lets recycle |
1739 | * the 'flags' field we are not using for beacons. | 1739 | * the 'flags' field we are not using for beacons. |
1740 | */ | 1740 | */ |
1741 | priv_bcn->guardian_data = 0; | 1741 | bcn_priv->guardian_data = 0; |
1742 | usb_fill_bulk_urb(priv_bcn->guardian_urb, usb_dev, pipe, | 1742 | usb_fill_bulk_urb(bcn_priv->guardian_urb, usb_dev, pipe, |
1743 | &priv_bcn->guardian_data, 1, rt2500usb_beacondone, | 1743 | &bcn_priv->guardian_data, 1, rt2500usb_beacondone, |
1744 | intf->beacon); | 1744 | intf->beacon); |
1745 | 1745 | ||
1746 | /* | 1746 | /* |
1747 | * Send out the guardian byte. | 1747 | * Send out the guardian byte. |
1748 | */ | 1748 | */ |
1749 | usb_submit_urb(priv_bcn->guardian_urb, GFP_ATOMIC); | 1749 | usb_submit_urb(bcn_priv->guardian_urb, GFP_ATOMIC); |
1750 | 1750 | ||
1751 | /* | 1751 | /* |
1752 | * Enable beacon generation. | 1752 | * Enable beacon generation. |
@@ -1797,14 +1797,14 @@ static const struct data_queue_desc rt2500usb_queue_rx = { | |||
1797 | .entry_num = RX_ENTRIES, | 1797 | .entry_num = RX_ENTRIES, |
1798 | .data_size = DATA_FRAME_SIZE, | 1798 | .data_size = DATA_FRAME_SIZE, |
1799 | .desc_size = RXD_DESC_SIZE, | 1799 | .desc_size = RXD_DESC_SIZE, |
1800 | .priv_size = sizeof(struct queue_entry_priv_usb_rx), | 1800 | .priv_size = sizeof(struct queue_entry_priv_usb), |
1801 | }; | 1801 | }; |
1802 | 1802 | ||
1803 | static const struct data_queue_desc rt2500usb_queue_tx = { | 1803 | static const struct data_queue_desc rt2500usb_queue_tx = { |
1804 | .entry_num = TX_ENTRIES, | 1804 | .entry_num = TX_ENTRIES, |
1805 | .data_size = DATA_FRAME_SIZE, | 1805 | .data_size = DATA_FRAME_SIZE, |
1806 | .desc_size = TXD_DESC_SIZE, | 1806 | .desc_size = TXD_DESC_SIZE, |
1807 | .priv_size = sizeof(struct queue_entry_priv_usb_tx), | 1807 | .priv_size = sizeof(struct queue_entry_priv_usb), |
1808 | }; | 1808 | }; |
1809 | 1809 | ||
1810 | static const struct data_queue_desc rt2500usb_queue_bcn = { | 1810 | static const struct data_queue_desc rt2500usb_queue_bcn = { |
@@ -1818,7 +1818,7 @@ static const struct data_queue_desc rt2500usb_queue_atim = { | |||
1818 | .entry_num = ATIM_ENTRIES, | 1818 | .entry_num = ATIM_ENTRIES, |
1819 | .data_size = DATA_FRAME_SIZE, | 1819 | .data_size = DATA_FRAME_SIZE, |
1820 | .desc_size = TXD_DESC_SIZE, | 1820 | .desc_size = TXD_DESC_SIZE, |
1821 | .priv_size = sizeof(struct queue_entry_priv_usb_tx), | 1821 | .priv_size = sizeof(struct queue_entry_priv_usb), |
1822 | }; | 1822 | }; |
1823 | 1823 | ||
1824 | static const struct rt2x00_ops rt2500usb_ops = { | 1824 | static const struct rt2x00_ops rt2500usb_ops = { |
@@ -1827,6 +1827,7 @@ static const struct rt2x00_ops rt2500usb_ops = { | |||
1827 | .max_ap_intf = 1, | 1827 | .max_ap_intf = 1, |
1828 | .eeprom_size = EEPROM_SIZE, | 1828 | .eeprom_size = EEPROM_SIZE, |
1829 | .rf_size = RF_SIZE, | 1829 | .rf_size = RF_SIZE, |
1830 | .tx_queues = NUM_TX_QUEUES, | ||
1830 | .rx = &rt2500usb_queue_rx, | 1831 | .rx = &rt2500usb_queue_rx, |
1831 | .tx = &rt2500usb_queue_tx, | 1832 | .tx = &rt2500usb_queue_tx, |
1832 | .bcn = &rt2500usb_queue_bcn, | 1833 | .bcn = &rt2500usb_queue_bcn, |