diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2500pci.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500pci.c | 54 |
1 files changed, 29 insertions, 25 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 2a73f593aab0..89d132d4af12 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
@@ -574,6 +574,10 @@ static void rt2500pci_config_ps(struct rt2x00_dev *rt2x00dev, | |||
574 | 574 | ||
575 | rt2x00_set_field32(®, CSR20_AUTOWAKE, 1); | 575 | rt2x00_set_field32(®, CSR20_AUTOWAKE, 1); |
576 | rt2x00pci_register_write(rt2x00dev, CSR20, reg); | 576 | rt2x00pci_register_write(rt2x00dev, CSR20, reg); |
577 | } else { | ||
578 | rt2x00pci_register_read(rt2x00dev, CSR20, ®); | ||
579 | rt2x00_set_field32(®, CSR20_AUTOWAKE, 0); | ||
580 | rt2x00pci_register_write(rt2x00dev, CSR20, reg); | ||
577 | } | 581 | } |
578 | 582 | ||
579 | rt2x00dev->ops->lib->set_device_state(rt2x00dev, state); | 583 | rt2x00dev->ops->lib->set_device_state(rt2x00dev, state); |
@@ -1161,15 +1165,15 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1161 | { | 1165 | { |
1162 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | 1166 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
1163 | struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data; | 1167 | struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data; |
1164 | __le32 *txd = skbdesc->desc; | 1168 | __le32 *txd = entry_priv->desc; |
1165 | u32 word; | 1169 | u32 word; |
1166 | 1170 | ||
1167 | /* | 1171 | /* |
1168 | * Start writing the descriptor words. | 1172 | * Start writing the descriptor words. |
1169 | */ | 1173 | */ |
1170 | rt2x00_desc_read(entry_priv->desc, 1, &word); | 1174 | rt2x00_desc_read(txd, 1, &word); |
1171 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); | 1175 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); |
1172 | rt2x00_desc_write(entry_priv->desc, 1, word); | 1176 | rt2x00_desc_write(txd, 1, word); |
1173 | 1177 | ||
1174 | rt2x00_desc_read(txd, 2, &word); | 1178 | rt2x00_desc_read(txd, 2, &word); |
1175 | rt2x00_set_field32(&word, TXD_W2_IV_OFFSET, IEEE80211_HEADER); | 1179 | rt2x00_set_field32(&word, TXD_W2_IV_OFFSET, IEEE80211_HEADER); |
@@ -1190,6 +1194,11 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1190 | test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)); | 1194 | test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)); |
1191 | rt2x00_desc_write(txd, 10, word); | 1195 | rt2x00_desc_write(txd, 10, word); |
1192 | 1196 | ||
1197 | /* | ||
1198 | * Writing TXD word 0 must the last to prevent a race condition with | ||
1199 | * the device, whereby the device may take hold of the TXD before we | ||
1200 | * finished updating it. | ||
1201 | */ | ||
1193 | rt2x00_desc_read(txd, 0, &word); | 1202 | rt2x00_desc_read(txd, 0, &word); |
1194 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1); | 1203 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1); |
1195 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); | 1204 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); |
@@ -1205,15 +1214,22 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1205 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); | 1214 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1206 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | 1215 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, |
1207 | test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); | 1216 | test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); |
1208 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skb->len); | 1217 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, txdesc->length); |
1209 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); | 1218 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); |
1210 | rt2x00_desc_write(txd, 0, word); | 1219 | rt2x00_desc_write(txd, 0, word); |
1220 | |||
1221 | /* | ||
1222 | * Register descriptor details in skb frame descriptor. | ||
1223 | */ | ||
1224 | skbdesc->desc = txd; | ||
1225 | skbdesc->desc_len = TXD_DESC_SIZE; | ||
1211 | } | 1226 | } |
1212 | 1227 | ||
1213 | /* | 1228 | /* |
1214 | * TX data initialization | 1229 | * TX data initialization |
1215 | */ | 1230 | */ |
1216 | static void rt2500pci_write_beacon(struct queue_entry *entry) | 1231 | static void rt2500pci_write_beacon(struct queue_entry *entry, |
1232 | struct txentry_desc *txdesc) | ||
1217 | { | 1233 | { |
1218 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 1234 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
1219 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | 1235 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; |
@@ -1229,20 +1245,19 @@ static void rt2500pci_write_beacon(struct queue_entry *entry) | |||
1229 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | 1245 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); |
1230 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | 1246 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); |
1231 | 1247 | ||
1232 | /* | ||
1233 | * Replace rt2x00lib allocated descriptor with the | ||
1234 | * pointer to the _real_ hardware descriptor. | ||
1235 | * After that, map the beacon to DMA and update the | ||
1236 | * descriptor. | ||
1237 | */ | ||
1238 | memcpy(entry_priv->desc, skbdesc->desc, skbdesc->desc_len); | ||
1239 | skbdesc->desc = entry_priv->desc; | ||
1240 | |||
1241 | rt2x00queue_map_txskb(rt2x00dev, entry->skb); | 1248 | rt2x00queue_map_txskb(rt2x00dev, entry->skb); |
1242 | 1249 | ||
1243 | rt2x00_desc_read(entry_priv->desc, 1, &word); | 1250 | rt2x00_desc_read(entry_priv->desc, 1, &word); |
1244 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); | 1251 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); |
1245 | rt2x00_desc_write(entry_priv->desc, 1, word); | 1252 | rt2x00_desc_write(entry_priv->desc, 1, word); |
1253 | |||
1254 | /* | ||
1255 | * Enable beaconing again. | ||
1256 | */ | ||
1257 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); | ||
1258 | rt2x00_set_field32(®, CSR14_TBCN, 1); | ||
1259 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); | ||
1260 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
1246 | } | 1261 | } |
1247 | 1262 | ||
1248 | static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1263 | static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
@@ -1250,17 +1265,6 @@ static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1250 | { | 1265 | { |
1251 | u32 reg; | 1266 | u32 reg; |
1252 | 1267 | ||
1253 | if (queue == QID_BEACON) { | ||
1254 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | ||
1255 | if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) { | ||
1256 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); | ||
1257 | rt2x00_set_field32(®, CSR14_TBCN, 1); | ||
1258 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); | ||
1259 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
1260 | } | ||
1261 | return; | ||
1262 | } | ||
1263 | |||
1264 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); | 1268 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); |
1265 | rt2x00_set_field32(®, TXCSR0_KICK_PRIO, (queue == QID_AC_BE)); | 1269 | rt2x00_set_field32(®, TXCSR0_KICK_PRIO, (queue == QID_AC_BE)); |
1266 | rt2x00_set_field32(®, TXCSR0_KICK_TX, (queue == QID_AC_BK)); | 1270 | rt2x00_set_field32(®, TXCSR0_KICK_TX, (queue == QID_AC_BK)); |