aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2x00queue.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00queue.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c193
1 files changed, 100 insertions, 93 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 01125563aba3..f4a951338f8f 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -148,20 +148,105 @@ void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
148 dev_kfree_skb_any(skb); 148 dev_kfree_skb_any(skb);
149} 149}
150 150
151static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry,
152 struct txentry_desc *txdesc)
153{
154 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
155 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data;
156 struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif);
157 unsigned long irqflags;
158
159 if (!(tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) ||
160 unlikely(!tx_info->control.vif))
161 return;
162
163 /*
164 * Hardware should insert sequence counter.
165 * FIXME: We insert a software sequence counter first for
166 * hardware that doesn't support hardware sequence counting.
167 *
168 * This is wrong because beacons are not getting sequence
169 * numbers assigned properly.
170 *
171 * A secondary problem exists for drivers that cannot toggle
172 * sequence counting per-frame, since those will override the
173 * sequence counter given by mac80211.
174 */
175 spin_lock_irqsave(&intf->seqlock, irqflags);
176
177 if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags))
178 intf->seqno += 0x10;
179 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
180 hdr->seq_ctrl |= cpu_to_le16(intf->seqno);
181
182 spin_unlock_irqrestore(&intf->seqlock, irqflags);
183
184 __set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags);
185}
186
187static void rt2x00queue_create_tx_descriptor_plcp(struct queue_entry *entry,
188 struct txentry_desc *txdesc,
189 const struct rt2x00_rate *hwrate)
190{
191 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
192 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
193 struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0];
194 unsigned int data_length;
195 unsigned int duration;
196 unsigned int residual;
197
198 /* Data length + CRC + Crypto overhead (IV/EIV/ICV/MIC) */
199 data_length = entry->skb->len + 4;
200 data_length += rt2x00crypto_tx_overhead(rt2x00dev, entry->skb);
201
202 /*
203 * PLCP setup
204 * Length calculation depends on OFDM/CCK rate.
205 */
206 txdesc->signal = hwrate->plcp;
207 txdesc->service = 0x04;
208
209 if (hwrate->flags & DEV_RATE_OFDM) {
210 txdesc->length_high = (data_length >> 6) & 0x3f;
211 txdesc->length_low = data_length & 0x3f;
212 } else {
213 /*
214 * Convert length to microseconds.
215 */
216 residual = GET_DURATION_RES(data_length, hwrate->bitrate);
217 duration = GET_DURATION(data_length, hwrate->bitrate);
218
219 if (residual != 0) {
220 duration++;
221
222 /*
223 * Check if we need to set the Length Extension
224 */
225 if (hwrate->bitrate == 110 && residual <= 30)
226 txdesc->service |= 0x80;
227 }
228
229 txdesc->length_high = (duration >> 8) & 0xff;
230 txdesc->length_low = duration & 0xff;
231
232 /*
233 * When preamble is enabled we should set the
234 * preamble bit for the signal.
235 */
236 if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
237 txdesc->signal |= 0x08;
238 }
239}
240
151static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, 241static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
152 struct txentry_desc *txdesc) 242 struct txentry_desc *txdesc)
153{ 243{
154 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 244 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
155 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); 245 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
156 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; 246 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data;
157 struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0];
158 struct ieee80211_rate *rate = 247 struct ieee80211_rate *rate =
159 ieee80211_get_tx_rate(rt2x00dev->hw, tx_info); 248 ieee80211_get_tx_rate(rt2x00dev->hw, tx_info);
160 const struct rt2x00_rate *hwrate; 249 const struct rt2x00_rate *hwrate;
161 unsigned int data_length;
162 unsigned int duration;
163 unsigned int residual;
164 unsigned long irqflags;
165 250
166 memset(txdesc, 0, sizeof(*txdesc)); 251 memset(txdesc, 0, sizeof(*txdesc));
167 252
@@ -173,27 +258,12 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
173 txdesc->cw_max = entry->queue->cw_max; 258 txdesc->cw_max = entry->queue->cw_max;
174 txdesc->aifs = entry->queue->aifs; 259 txdesc->aifs = entry->queue->aifs;
175 260
176 /* Data length + CRC */
177 data_length = entry->skb->len + 4;
178
179 /* 261 /*
180 * Check whether this frame is to be acked. 262 * Check whether this frame is to be acked.
181 */ 263 */
182 if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) 264 if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK))
183 __set_bit(ENTRY_TXD_ACK, &txdesc->flags); 265 __set_bit(ENTRY_TXD_ACK, &txdesc->flags);
184 266
185 if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags) &&
186 !entry->skb->do_not_encrypt) {
187 /* Apply crypto specific descriptor information */
188 rt2x00crypto_create_tx_descriptor(entry, txdesc);
189
190 /*
191 * Extend frame length to include all encryption overhead
192 * that will be added by the hardware.
193 */
194 data_length += rt2x00crypto_tx_overhead(tx_info);
195 }
196
197 /* 267 /*
198 * Check if this is a RTS/CTS frame 268 * Check if this is a RTS/CTS frame
199 */ 269 */
@@ -237,86 +307,23 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
237 * Set ifs to IFS_SIFS when the this is not the first fragment, 307 * Set ifs to IFS_SIFS when the this is not the first fragment,
238 * or this fragment came after RTS/CTS. 308 * or this fragment came after RTS/CTS.
239 */ 309 */
240 if (test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)) { 310 if ((tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) &&
241 txdesc->ifs = IFS_SIFS; 311 !test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)) {
242 } else if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) {
243 __set_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags); 312 __set_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags);
244 txdesc->ifs = IFS_BACKOFF; 313 txdesc->ifs = IFS_BACKOFF;
245 } else { 314 } else
246 txdesc->ifs = IFS_SIFS; 315 txdesc->ifs = IFS_SIFS;
247 }
248 316
249 /*
250 * Hardware should insert sequence counter.
251 * FIXME: We insert a software sequence counter first for
252 * hardware that doesn't support hardware sequence counting.
253 *
254 * This is wrong because beacons are not getting sequence
255 * numbers assigned properly.
256 *
257 * A secondary problem exists for drivers that cannot toggle
258 * sequence counting per-frame, since those will override the
259 * sequence counter given by mac80211.
260 */
261 if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
262 if (likely(tx_info->control.vif)) {
263 struct rt2x00_intf *intf;
264
265 intf = vif_to_intf(tx_info->control.vif);
266
267 spin_lock_irqsave(&intf->seqlock, irqflags);
268
269 if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags))
270 intf->seqno += 0x10;
271 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
272 hdr->seq_ctrl |= cpu_to_le16(intf->seqno);
273
274 spin_unlock_irqrestore(&intf->seqlock, irqflags);
275
276 __set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags);
277 }
278 }
279
280 /*
281 * PLCP setup
282 * Length calculation depends on OFDM/CCK rate.
283 */
284 hwrate = rt2x00_get_rate(rate->hw_value); 317 hwrate = rt2x00_get_rate(rate->hw_value);
285 txdesc->signal = hwrate->plcp; 318 if (hwrate->flags & DEV_RATE_OFDM)
286 txdesc->service = 0x04;
287
288 if (hwrate->flags & DEV_RATE_OFDM) {
289 __set_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags); 319 __set_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags);
290 320
291 txdesc->length_high = (data_length >> 6) & 0x3f; 321 /*
292 txdesc->length_low = data_length & 0x3f; 322 * Apply TX descriptor handling by components
293 } else { 323 */
294 /* 324 rt2x00crypto_create_tx_descriptor(entry, txdesc);
295 * Convert length to microseconds. 325 rt2x00queue_create_tx_descriptor_seq(entry, txdesc);
296 */ 326 rt2x00queue_create_tx_descriptor_plcp(entry, txdesc, hwrate);
297 residual = GET_DURATION_RES(data_length, hwrate->bitrate);
298 duration = GET_DURATION(data_length, hwrate->bitrate);
299
300 if (residual != 0) {
301 duration++;
302
303 /*
304 * Check if we need to set the Length Extension
305 */
306 if (hwrate->bitrate == 110 && residual <= 30)
307 txdesc->service |= 0x80;
308 }
309
310 txdesc->length_high = (duration >> 8) & 0xff;
311 txdesc->length_low = duration & 0xff;
312
313 /*
314 * When preamble is enabled we should set the
315 * preamble bit for the signal.
316 */
317 if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
318 txdesc->signal |= 0x08;
319 }
320} 327}
321 328
322static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, 329static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry,