[package] mac80211: add rt2800 patches from the rt2x00 git rope
[openwrt.git] / package / mac80211 / patches / 301-rt2x00-Implement-support-for-802.11n.patch
1 From 2c0af6ef6263ad5b581429953ad1b98e6d522e69 Mon Sep 17 00:00:00 2001
2 From: Ivo van Doorn <IvDoorn@gmail.com>
3 Date: Wed, 4 Feb 2009 20:10:23 +0100
4 Subject: [PATCH] rt2x00: Implement support for 802.11n
5
6 Extend rt2x00lib capabilities to support 802.11n,
7 it still lacks aggregation support, but that can
8 be added in the future.
9
10 Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
11 ---
12  drivers/net/wireless/rt2x00/Kconfig        |    3 +
13  drivers/net/wireless/rt2x00/Makefile       |    1 +
14  drivers/net/wireless/rt2x00/rt2x00.h       |    4 +
15  drivers/net/wireless/rt2x00/rt2x00config.c |    5 ++
16  drivers/net/wireless/rt2x00/rt2x00dev.c    |   91 ++++++++++++++++++++-------
17  drivers/net/wireless/rt2x00/rt2x00ht.c     |   69 +++++++++++++++++++++
18  drivers/net/wireless/rt2x00/rt2x00lib.h    |   24 +++++++
19  drivers/net/wireless/rt2x00/rt2x00queue.c  |    1 +
20  drivers/net/wireless/rt2x00/rt2x00queue.h  |   33 ++++++++--
21  9 files changed, 201 insertions(+), 30 deletions(-)
22  create mode 100644 drivers/net/wireless/rt2x00/rt2x00ht.c
23
24 --- a/drivers/net/wireless/rt2x00/Makefile
25 +++ b/drivers/net/wireless/rt2x00/Makefile
26 @@ -8,6 +8,7 @@ rt2x00lib-$(CONFIG_RT2X00_LIB_CRYPTO)   +=
27  rt2x00lib-$(CONFIG_RT2X00_LIB_RFKILL)  += rt2x00rfkill.o
28  rt2x00lib-$(CONFIG_RT2X00_LIB_FIRMWARE)        += rt2x00firmware.o
29  rt2x00lib-$(CONFIG_RT2X00_LIB_LEDS)    += rt2x00leds.o
30 +rt2x00lib-$(CONFIG_RT2X00_LIB_HT)      += rt2x00ht.o
31  
32  obj-$(CONFIG_RT2X00_LIB)               += rt2x00lib.o
33  obj-$(CONFIG_RT2X00_LIB_PCI)           += rt2x00pci.o
34 --- a/drivers/net/wireless/rt2x00/rt2x00.h
35 +++ b/drivers/net/wireless/rt2x00/rt2x00.h
36 @@ -357,6 +357,7 @@ static inline struct rt2x00_intf* vif_to
37   *     for @tx_power_a, @tx_power_bg and @channels.
38   * @channels: Device/chipset specific channel values (See &struct rf_channel).
39   * @channels_info: Additional information for channels (See &struct channel_info).
40 + * @ht: Driver HT Capabilities (See &ieee80211_sta_ht_cap).
41   */
42  struct hw_mode_spec {
43         unsigned int supported_bands;
44 @@ -370,6 +371,8 @@ struct hw_mode_spec {
45         unsigned int num_channels;
46         const struct rf_channel *channels;
47         const struct channel_info *channels_info;
48 +
49 +       struct ieee80211_sta_ht_cap ht;
50  };
51  
52  /*
53 @@ -606,6 +609,7 @@ enum rt2x00_flags {
54         CONFIG_EXTERNAL_LNA_BG,
55         CONFIG_DOUBLE_ANTENNA,
56         CONFIG_DISABLE_LINK_TUNING,
57 +       CONFIG_CHANNEL_HT40,
58  };
59  
60  /*
61 --- a/drivers/net/wireless/rt2x00/rt2x00config.c
62 +++ b/drivers/net/wireless/rt2x00/rt2x00config.c
63 @@ -173,6 +173,11 @@ void rt2x00lib_config(struct rt2x00_dev 
64         libconf.conf = conf;
65  
66         if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL) {
67 +               if (conf_is_ht40(conf))
68 +                       __set_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags);
69 +               else
70 +                       __clear_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags);
71 +
72                 memcpy(&libconf.rf,
73                        &rt2x00dev->spec.channels[conf->channel->hw_value],
74                        sizeof(libconf.rf));
75 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c
76 +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
77 @@ -316,18 +316,54 @@ void rt2x00lib_txdone(struct queue_entry
78  }
79  EXPORT_SYMBOL_GPL(rt2x00lib_txdone);
80  
81 +static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev,
82 +                                       struct rxdone_entry_desc *rxdesc)
83 +{
84 +       struct ieee80211_supported_band *sband;
85 +       const struct rt2x00_rate *rate;
86 +       unsigned int i;
87 +       int signal;
88 +       int type;
89 +
90 +       /*
91 +        * For non-HT rates the MCS value needs to contain the
92 +        * actually used rate modulation (CCK or OFDM).
93 +        */
94 +       if (rxdesc->dev_flags & RXDONE_SIGNAL_MCS)
95 +               signal = RATE_MCS(rxdesc->rate_mode, rxdesc->signal);
96 +       else
97 +               signal = rxdesc->signal;
98 +
99 +       type = (rxdesc->dev_flags & RXDONE_SIGNAL_MASK);
100 +
101 +       sband = &rt2x00dev->bands[rt2x00dev->curr_band];
102 +       for (i = 0; i < sband->n_bitrates; i++) {
103 +               rate = rt2x00_get_rate(sband->bitrates[i].hw_value);
104 +
105 +               if (((type == RXDONE_SIGNAL_PLCP) &&
106 +                    (rate->plcp == signal)) ||
107 +                   ((type == RXDONE_SIGNAL_BITRATE) &&
108 +                     (rate->bitrate == signal)) ||
109 +                   ((type == RXDONE_SIGNAL_MCS) &&
110 +                     (rate->mcs == signal))) {
111 +                       return i;
112 +               }
113 +       }
114 +
115 +       WARNING(rt2x00dev, "Frame received with unrecognized signal, "
116 +               "signal=0x%.4x, type=%d.\n", signal, type);
117 +       return 0;
118 +}
119 +
120  void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
121                       struct queue_entry *entry)
122  {
123         struct rxdone_entry_desc rxdesc;
124         struct sk_buff *skb;
125         struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status;
126 -       struct ieee80211_supported_band *sband;
127 -       const struct rt2x00_rate *rate;
128         unsigned int header_length;
129         unsigned int align;
130 -       unsigned int i;
131 -       int idx = -1;
132 +       int rate_idx;
133  
134         /*
135          * Allocate a new sk_buffer. If no new buffer available, drop the
136 @@ -376,26 +412,17 @@ void rt2x00lib_rxdone(struct rt2x00_dev 
137         skb_trim(entry->skb, rxdesc.size);
138  
139         /*
140 -        * Update RX statistics.
141 -        */
142 -       sband = &rt2x00dev->bands[rt2x00dev->curr_band];
143 -       for (i = 0; i < sband->n_bitrates; i++) {
144 -               rate = rt2x00_get_rate(sband->bitrates[i].hw_value);
145 -
146 -               if (((rxdesc.dev_flags & RXDONE_SIGNAL_PLCP) &&
147 -                    (rate->plcp == rxdesc.signal)) ||
148 -                   ((rxdesc.dev_flags & RXDONE_SIGNAL_BITRATE) &&
149 -                     (rate->bitrate == rxdesc.signal))) {
150 -                       idx = i;
151 -                       break;
152 -               }
153 -       }
154 -
155 -       if (idx < 0) {
156 -               WARNING(rt2x00dev, "Frame received with unrecognized signal,"
157 -                       "signal=0x%.2x, type=%d.\n", rxdesc.signal,
158 -                       (rxdesc.dev_flags & RXDONE_SIGNAL_MASK));
159 -               idx = 0;
160 +        * Check if the frame was received using HT. In that case,
161 +        * the rate is the MCS index and should be passed to mac80211
162 +        * directly. Otherwise we need to translate the signal to
163 +        * the correct bitrate index.
164 +        */
165 +       if (rxdesc.rate_mode == RATE_MODE_CCK ||
166 +           rxdesc.rate_mode == RATE_MODE_OFDM) {
167 +               rate_idx = rt2x00lib_rxdone_read_signal(rt2x00dev, &rxdesc);
168 +       } else {
169 +               rxdesc.flags |= RX_FLAG_HT;
170 +               rate_idx = rxdesc.signal;
171         }
172  
173         /*
174 @@ -405,7 +432,7 @@ void rt2x00lib_rxdone(struct rt2x00_dev 
175         rt2x00debug_update_crypto(rt2x00dev, &rxdesc);
176  
177         rx_status->mactime = rxdesc.timestamp;
178 -       rx_status->rate_idx = idx;
179 +       rx_status->rate_idx = rate_idx;
180         rx_status->qual = rt2x00link_calculate_signal(rt2x00dev, rxdesc.rssi);
181         rx_status->signal = rxdesc.rssi;
182         rx_status->noise = rxdesc.noise;
183 @@ -440,72 +467,84 @@ const struct rt2x00_rate rt2x00_supporte
184                 .bitrate = 10,
185                 .ratemask = BIT(0),
186                 .plcp = 0x00,
187 +               .mcs = RATE_MCS(RATE_MODE_CCK, 0),
188         },
189         {
190                 .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
191                 .bitrate = 20,
192                 .ratemask = BIT(1),
193                 .plcp = 0x01,
194 +               .mcs = RATE_MCS(RATE_MODE_CCK, 1),
195         },
196         {
197                 .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
198                 .bitrate = 55,
199                 .ratemask = BIT(2),
200                 .plcp = 0x02,
201 +               .mcs = RATE_MCS(RATE_MODE_CCK, 2),
202         },
203         {
204                 .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
205                 .bitrate = 110,
206                 .ratemask = BIT(3),
207                 .plcp = 0x03,
208 +               .mcs = RATE_MCS(RATE_MODE_CCK, 3),
209         },
210         {
211                 .flags = DEV_RATE_OFDM,
212                 .bitrate = 60,
213                 .ratemask = BIT(4),
214                 .plcp = 0x0b,
215 +               .mcs = RATE_MCS(RATE_MODE_OFDM, 0),
216         },
217         {
218                 .flags = DEV_RATE_OFDM,
219                 .bitrate = 90,
220                 .ratemask = BIT(5),
221                 .plcp = 0x0f,
222 +               .mcs = RATE_MCS(RATE_MODE_OFDM, 1),
223         },
224         {
225                 .flags = DEV_RATE_OFDM,
226                 .bitrate = 120,
227                 .ratemask = BIT(6),
228                 .plcp = 0x0a,
229 +               .mcs = RATE_MCS(RATE_MODE_OFDM, 2),
230         },
231         {
232                 .flags = DEV_RATE_OFDM,
233                 .bitrate = 180,
234                 .ratemask = BIT(7),
235                 .plcp = 0x0e,
236 +               .mcs = RATE_MCS(RATE_MODE_OFDM, 3),
237         },
238         {
239                 .flags = DEV_RATE_OFDM,
240                 .bitrate = 240,
241                 .ratemask = BIT(8),
242                 .plcp = 0x09,
243 +               .mcs = RATE_MCS(RATE_MODE_OFDM, 4),
244         },
245         {
246                 .flags = DEV_RATE_OFDM,
247                 .bitrate = 360,
248                 .ratemask = BIT(9),
249                 .plcp = 0x0d,
250 +               .mcs = RATE_MCS(RATE_MODE_OFDM, 5),
251         },
252         {
253                 .flags = DEV_RATE_OFDM,
254                 .bitrate = 480,
255                 .ratemask = BIT(10),
256                 .plcp = 0x08,
257 +               .mcs = RATE_MCS(RATE_MODE_OFDM, 6),
258         },
259         {
260                 .flags = DEV_RATE_OFDM,
261                 .bitrate = 540,
262                 .ratemask = BIT(11),
263                 .plcp = 0x0c,
264 +               .mcs = RATE_MCS(RATE_MODE_OFDM, 7),
265         },
266  };
267  
268 @@ -581,6 +620,8 @@ static int rt2x00lib_probe_hw_modes(stru
269                 rt2x00dev->bands[IEEE80211_BAND_2GHZ].bitrates = rates;
270                 hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
271                     &rt2x00dev->bands[IEEE80211_BAND_2GHZ];
272 +               memcpy(&rt2x00dev->bands[IEEE80211_BAND_2GHZ].ht_cap,
273 +                      &spec->ht, sizeof(spec->ht));
274         }
275  
276         /*
277 @@ -597,6 +638,8 @@ static int rt2x00lib_probe_hw_modes(stru
278                 rt2x00dev->bands[IEEE80211_BAND_5GHZ].bitrates = &rates[4];
279                 hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
280                     &rt2x00dev->bands[IEEE80211_BAND_5GHZ];
281 +               memcpy(&rt2x00dev->bands[IEEE80211_BAND_5GHZ].ht_cap,
282 +                      &spec->ht, sizeof(spec->ht));
283         }
284  
285         return 0;
286 --- /dev/null
287 +++ b/drivers/net/wireless/rt2x00/rt2x00ht.c
288 @@ -0,0 +1,69 @@
289 +/*
290 +       Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
291 +       <http://rt2x00.serialmonkey.com>
292 +
293 +       This program is free software; you can redistribute it and/or modify
294 +       it under the terms of the GNU General Public License as published by
295 +       the Free Software Foundation; either version 2 of the License, or
296 +       (at your option) any later version.
297 +
298 +       This program is distributed in the hope that it will be useful,
299 +       but WITHOUT ANY WARRANTY; without even the implied warranty of
300 +       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
301 +       GNU General Public License for more details.
302 +
303 +       You should have received a copy of the GNU General Public License
304 +       along with this program; if not, write to the
305 +       Free Software Foundation, Inc.,
306 +       59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
307 + */
308 +
309 +/*
310 +       Module: rt2x00lib
311 +       Abstract: rt2x00 HT specific routines.
312 + */
313 +
314 +#include <linux/kernel.h>
315 +#include <linux/module.h>
316 +
317 +#include "rt2x00.h"
318 +#include "rt2x00lib.h"
319 +
320 +void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
321 +                                  struct txentry_desc *txdesc,
322 +                                  const struct rt2x00_rate *hwrate)
323 +{
324 +       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
325 +       struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0];
326 +
327 +       if (tx_info->control.sta)
328 +               txdesc->mpdu_density =
329 +                   tx_info->control.sta->ht_cap.ampdu_density;
330 +       else
331 +               txdesc->mpdu_density = 0;
332 +
333 +       txdesc->ba_size = 7;    /* FIXME: What value is needed? */
334 +       txdesc->stbc = 0;       /* FIXME: What value is needed? */
335 +
336 +       txdesc->mcs = rt2x00_get_rate_mcs(hwrate->mcs);
337 +       if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
338 +               txdesc->mcs |= 0x08;
339 +
340 +       /*
341 +        * Convert flags
342 +        */
343 +       if (tx_info->flags & IEEE80211_TX_CTL_AMPDU)
344 +               __set_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags);
345 +
346 +       /*
347 +        * Determine HT Mix/Greenfield rate mode
348 +        */
349 +       if (txrate->flags & IEEE80211_TX_RC_MCS)
350 +               txdesc->rate_mode = RATE_MODE_HT_MIX;
351 +       if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD)
352 +               txdesc->rate_mode = RATE_MODE_HT_GREENFIELD;
353 +       if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
354 +               __set_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags);
355 +       if (txrate->flags & IEEE80211_TX_RC_SHORT_GI)
356 +               __set_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags);
357 +}
358 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h
359 +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
360 @@ -48,6 +48,7 @@ struct rt2x00_rate {
361         unsigned short ratemask;
362  
363         unsigned short plcp;
364 +       unsigned short mcs;
365  };
366  
367  extern const struct rt2x00_rate rt2x00_supported_rates[12];
368 @@ -57,6 +58,14 @@ static inline const struct rt2x00_rate *
369         return &rt2x00_supported_rates[hw_value & 0xff];
370  }
371  
372 +#define RATE_MCS(__mode, __mcs) \
373 +       ( (((__mode) & 0x00ff) << 8) | ((__mcs) & 0x00ff) )
374 +
375 +static inline int rt2x00_get_rate_mcs(const u16 mcs_value)
376 +{
377 +       return (mcs_value & 0x00ff);
378 +}
379 +
380  /*
381   * Radio control handlers.
382   */
383 @@ -341,6 +350,21 @@ static inline void rt2x00crypto_rx_inser
384  #endif /* CONFIG_RT2X00_LIB_CRYPTO */
385  
386  /*
387 + * HT handlers.
388 + */
389 +#ifdef CONFIG_RT2X00_LIB_HT
390 +void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
391 +                                  struct txentry_desc *txdesc,
392 +                                  const struct rt2x00_rate *hwrate);
393 +#else
394 +static inline void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
395 +                                                struct txentry_desc *txdesc,
396 +                                                const struct rt2x00_rate *hwrate)
397 +{
398 +}
399 +#endif /* CONFIG_RT2X00_LIB_HT */
400 +
401 +/*
402   * RFkill handlers.
403   */
404  #ifdef CONFIG_RT2X00_LIB_RFKILL
405 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c
406 +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
407 @@ -326,6 +326,7 @@ static void rt2x00queue_create_tx_descri
408          * Apply TX descriptor handling by components
409          */
410         rt2x00crypto_create_tx_descriptor(entry, txdesc);
411 +       rt2x00ht_create_tx_descriptor(entry, txdesc, hwrate);
412         rt2x00queue_create_tx_descriptor_seq(entry, txdesc);
413         rt2x00queue_create_tx_descriptor_plcp(entry, txdesc, hwrate);
414  }
415 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h
416 +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
417 @@ -35,9 +35,12 @@
418   * for USB devices this restriction does not apply, but the value of
419   * 2432 makes sense since it is big enough to contain the maximum fragment
420   * size according to the ieee802.11 specs.
421 + * The aggregation size depends on support from the driver, but should
422 + * be something around 3840 bytes.
423   */
424 -#define DATA_FRAME_SIZE        2432
425 -#define MGMT_FRAME_SIZE        256
426 +#define DATA_FRAME_SIZE                2432
427 +#define MGMT_FRAME_SIZE                256
428 +#define AGGREGATION_SIZE       3840
429  
430  /**
431   * DOC: Number of entries per queue
432 @@ -145,6 +148,7 @@ static inline struct skb_frame_desc* get
433   *
434   * @RXDONE_SIGNAL_PLCP: Signal field contains the plcp value.
435   * @RXDONE_SIGNAL_BITRATE: Signal field contains the bitrate value.
436 + * @RXDONE_SIGNAL_MCS: Signal field contains the mcs value.
437   * @RXDONE_MY_BSS: Does this frame originate from device's BSS.
438   * @RXDONE_CRYPTO_IV: Driver provided IV/EIV data.
439   * @RXDONE_CRYPTO_ICV: Driver provided ICV data.
440 @@ -152,9 +156,10 @@ static inline struct skb_frame_desc* get
441  enum rxdone_entry_desc_flags {
442         RXDONE_SIGNAL_PLCP = 1 << 0,
443         RXDONE_SIGNAL_BITRATE = 1 << 1,
444 -       RXDONE_MY_BSS = 1 << 2,
445 -       RXDONE_CRYPTO_IV = 1 << 3,
446 -       RXDONE_CRYPTO_ICV = 1 << 4,
447 +       RXDONE_SIGNAL_MCS = 1 << 2,
448 +       RXDONE_MY_BSS = 1 << 3,
449 +       RXDONE_CRYPTO_IV = 1 << 4,
450 +       RXDONE_CRYPTO_ICV = 1 << 5,
451  };
452  
453  /**
454 @@ -163,7 +168,7 @@ enum rxdone_entry_desc_flags {
455   * from &rxdone_entry_desc to a signal value type.
456   */
457  #define RXDONE_SIGNAL_MASK \
458 -       ( RXDONE_SIGNAL_PLCP | RXDONE_SIGNAL_BITRATE )
459 +       ( RXDONE_SIGNAL_PLCP | RXDONE_SIGNAL_BITRATE | RXDONE_SIGNAL_MCS )
460  
461  /**
462   * struct rxdone_entry_desc: RX Entry descriptor
463 @@ -177,6 +182,7 @@ enum rxdone_entry_desc_flags {
464   * @size: Data size of the received frame.
465   * @flags: MAC80211 receive flags (See &enum mac80211_rx_flags).
466   * @dev_flags: Ralink receive flags (See &enum rxdone_entry_desc_flags).
467 + * @rate_mode: Rate mode (See @enum rate_modulation).
468   * @cipher: Cipher type used during decryption.
469   * @cipher_status: Decryption status.
470   * @iv: IV/EIV data used during decryption.
471 @@ -190,6 +196,7 @@ struct rxdone_entry_desc {
472         int size;
473         int flags;
474         int dev_flags;
475 +       u16 rate_mode;
476         u8 cipher;
477         u8 cipher_status;
478  
479 @@ -243,6 +250,9 @@ struct txdone_entry_desc {
480   * @ENTRY_TXD_ENCRYPT_PAIRWISE: Use pairwise key table (instead of shared).
481   * @ENTRY_TXD_ENCRYPT_IV: Generate IV/EIV in hardware.
482   * @ENTRY_TXD_ENCRYPT_MMIC: Generate MIC in hardware.
483 + * @ENTRY_TXD_HT_AMPDU: This frame is part of an AMPDU.
484 + * @ENTRY_TXD_HT_BW_40: Use 40MHz Bandwidth.
485 + * @ENTRY_TXD_HT_SHORT_GI: Use short GI.
486   */
487  enum txentry_desc_flags {
488         ENTRY_TXD_RTS_FRAME,
489 @@ -258,6 +268,9 @@ enum txentry_desc_flags {
490         ENTRY_TXD_ENCRYPT_PAIRWISE,
491         ENTRY_TXD_ENCRYPT_IV,
492         ENTRY_TXD_ENCRYPT_MMIC,
493 +       ENTRY_TXD_HT_AMPDU,
494 +       ENTRY_TXD_HT_BW_40,
495 +       ENTRY_TXD_HT_SHORT_GI,
496  };
497  
498  /**
499 @@ -271,7 +284,11 @@ enum txentry_desc_flags {
500   * @length_low: PLCP length low word.
501   * @signal: PLCP signal.
502   * @service: PLCP service.
503 + * @msc: MCS.
504 + * @stbc: STBC.
505 + * @ba_size: BA size.
506   * @rate_mode: Rate mode (See @enum rate_modulation).
507 + * @mpdu_density: MDPU density.
508   * @retry_limit: Max number of retries.
509   * @aifs: AIFS value.
510   * @ifs: IFS value.
511 @@ -291,7 +308,11 @@ struct txentry_desc {
512         u16 signal;
513         u16 service;
514  
515 +       u16 mcs;
516 +       u16 stbc;
517 +       u16 ba_size;
518         u16 rate_mode;
519 +       u16 mpdu_density;
520  
521         short retry_limit;
522         short aifs;